Jelajahi Sumber

Provide internal list of command names that can be enabled in exception.

Maciej Gołaszewski 6 tahun lalu
induk
melakukan
630ca10ee3

+ 6 - 4
packages/ckeditor5-restricted-editing/src/restrictedediting.js

@@ -28,6 +28,7 @@ export default class RestrictedEditing extends Plugin {
 		super( editor );
 
 		this._alwaysEnabled = new Set( [ 'undo', 'redo' ] );
+		this._allowedInException = new Set( [ 'bold', 'italic', 'link', 'input', 'delete' ] );
 	}
 
 	/**
@@ -63,6 +64,7 @@ export default class RestrictedEditing extends Plugin {
 		this._disableCommands( editor );
 
 		const selection = editor.model.document.selection;
+
 		this.listenTo( selection, 'change', () => {
 			const marker = Array.from( editor.model.markers.getMarkersAtPosition( selection.focus ) )
 				.find( marker => marker.name.startsWith( 'restricted-editing-exception:' ) );
@@ -78,7 +80,7 @@ export default class RestrictedEditing extends Plugin {
 	}
 
 	_enableCommands( editor ) {
-		const commands = this._getCommandsToToggle( editor );
+		const commands = this._getCommandsToToggle( editor, this._allowedInException );
 
 		for ( const command of commands ) {
 			command.clearForceDisabled( 'RestrictedMode' );
@@ -86,17 +88,17 @@ export default class RestrictedEditing extends Plugin {
 	}
 
 	_disableCommands( editor ) {
-		const names = Array.from( editor.commands.names() ).filter( name => !this._alwaysEnabled.has( name ) );
-		const commands = names.map( name => editor.commands.get( name ) );
+		const commands = this._getCommandsToToggle( editor );
 
 		for ( const command of commands ) {
 			command.forceDisabled( 'RestrictedMode' );
 		}
 	}
 
-	_getCommandsToToggle( editor ) {
+	_getCommandsToToggle( editor, fromSet ) {
 		return Array.from( editor.commands.names() )
 			.filter( name => !this._alwaysEnabled.has( name ) )
+			.filter( name => fromSet ? fromSet.has( name ) : true )
 			.map( name => editor.commands.get( name ) );
 	}
 }

+ 78 - 31
packages/ckeditor5-restricted-editing/tests/restrictedediting.js

@@ -16,6 +16,7 @@ import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
+import Command from '@ckeditor/ckeditor5-core/src/command';
 
 describe( 'RestrictedEditing', () => {
 	let editor, element;
@@ -210,37 +211,41 @@ describe( 'RestrictedEditing', () => {
 	} );
 
 	describe( 'commands integration', () => {
-		let model;
+		let model, firstParagraph;
 
 		beforeEach( async () => {
 			editor = await VirtualTestEditor.create( { plugins: [ Paragraph, Typing, UndoEditing, RestrictedEditing ] } );
 			model = editor.model;
+
+			setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );
+			firstParagraph = model.document.getRoot().getChild( 0 );
+
+			model.change( writer => {
+				writer.addMarker( 'restricted-editing-exception:1', {
+					range: writer.createRange(
+						writer.createPositionAt( firstParagraph, 4 ),
+						writer.createPositionAt( firstParagraph, 7 ) ),
+					usingOperation: true,
+					affectsData: true
+				} );
+			} );
 		} );
 
 		afterEach( async () => {
 			await editor.destroy();
 		} );
 
-		describe( 'undo command', () => {
+		describe( 'undo', () => {
 			it( 'should be enabled outside exception marker', () => {
-				setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );
+				model.change( writer => {
+					writer.setSelection( firstParagraph, 1 );
+				} );
 
 				expect( editor.commands.get( 'undo' ).isEnabled ).to.be.true;
 			} );
 
 			it( 'should be enabled inside exception marker', () => {
-				setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );
-				const firstParagraph = model.document.getRoot().getChild( 0 );
-
 				model.change( writer => {
-					writer.addMarker( 'restricted-editing-exception:1', {
-						range: writer.createRange(
-							writer.createPositionAt( firstParagraph, 4 ),
-							writer.createPositionAt( firstParagraph, 7 ) ),
-						usingOperation: true,
-						affectsData: true
-					} );
-
 					writer.setSelection( firstParagraph, 5 );
 				} );
 
@@ -248,41 +253,83 @@ describe( 'RestrictedEditing', () => {
 			} );
 		} );
 
-		describe( 'redo command', () => {
-			it( 'should be enabled outside exception marker', () => {
-				setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );
+		describe( 'redo', () => {
+			beforeEach( () => {
+				editor.commands.add( 'redo', buildFakeCommand( editor ) );
+			} );
 
+			it( 'should be enabled outside exception marker', () => {
 				model.change( writer => {
-					model.insertContent( writer.createText( 'R', model.document.selection.getAttributes() ) );
+					writer.setSelection( firstParagraph, 1 );
 				} );
-				editor.execute( 'undo' );
 
 				expect( editor.commands.get( 'redo' ).isEnabled ).to.be.true;
 			} );
 
 			it( 'should be enabled inside exception marker', () => {
-				setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );
-				const firstParagraph = model.document.getRoot().getChild( 0 );
+				model.change( writer => {
+					writer.setSelection( firstParagraph, 5 );
+				} );
+
+				expect( editor.commands.get( 'redo' ).isEnabled ).to.be.true;
+			} );
+		} );
+
+		describe( 'bold', () => {
+			beforeEach( () => {
+				editor.commands.add( 'bold', buildFakeCommand( editor ) );
+			} );
 
+			it( 'should be disabled outside exception marker', () => {
 				model.change( writer => {
-					model.insertContent( writer.createText( 'R', model.document.selection.getAttributes() ) );
+					writer.setSelection( firstParagraph, 1 );
 				} );
 
+				expect( editor.commands.get( 'bold' ).isEnabled ).to.be.false;
+			} );
+
+			it( 'should be enabled inside exception marker', () => {
 				model.change( writer => {
-					writer.addMarker( 'restricted-editing-exception:1', {
-						range: writer.createRange(
-							writer.createPositionAt( firstParagraph, 4 ),
-							writer.createPositionAt( firstParagraph, 7 ) ),
-						usingOperation: true,
-						affectsData: true
-					} );
+					writer.setSelection( firstParagraph, 5 );
+				} );
+
+				expect( editor.commands.get( 'bold' ).isEnabled ).to.be.true;
+			} );
+		} );
+
+		describe( 'other', () => {
+			beforeEach( () => {
+				editor.commands.add( 'other', buildFakeCommand( editor ) );
+			} );
+
+			it( 'should be disabled outside exception marker', () => {
+				model.change( writer => {
+					writer.setSelection( firstParagraph, 1 );
+				} );
+
+				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;
+			} );
 
+			it( 'should be disabled inside exception marker', () => {
+				model.change( writer => {
+					writer.setSelection( firstParagraph, 1 );
+				} );
+				model.change( writer => {
 					writer.setSelection( firstParagraph, 5 );
 				} );
-				editor.execute( 'undo' );
 
-				expect( editor.commands.get( 'redo' ).isEnabled ).to.be.true;
+				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;
 			} );
 		} );
 	} );
+
+	class FakeCommand extends Command {
+		refresh() {
+			this.isEnabled = true;
+		}
+	}
+
+	function buildFakeCommand( editor ) {
+		return new FakeCommand( editor );
+	}
 } );