8
0
فهرست منبع

Fix: Backspace at first LI should not merge with previous block.

Maciej Gołaszewski 8 سال پیش
والد
کامیت
7772972bb9
2فایلهای تغییر یافته به همراه84 افزوده شده و 0 حذف شده
  1. 22 0
      packages/ckeditor5-list/src/list.js
  2. 62 0
      packages/ckeditor5-list/tests/list.js

+ 22 - 0
packages/ckeditor5-list/src/list.js

@@ -61,6 +61,28 @@ export default class List extends Plugin {
 			}
 		} );
 
+		// Overwrite default Backspace key behavior.
+		// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it.
+		this.listenTo( this.editor.editing.view, 'delete', ( evt, data ) => {
+			const selection = this.editor.document.selection;
+			const positionParent = selection.getLastPosition().parent;
+
+			const isInListItem = positionParent.name === 'listItem';
+			const previousIsNotAListItem = !positionParent.previousSibling || positionParent.previousSibling.name !== 'listItem';
+
+			const isBackward = data.direction === 'backward';
+
+			const firstPosition = selection.getFirstPosition();
+			const isAtStart = firstPosition.isAtStart;
+
+			if ( isInListItem && previousIsNotAListItem && isBackward && selection.isCollapsed && isAtStart ) {
+				this.editor.execute( 'outdentList' );
+
+				data.preventDefault();
+				evt.stop();
+			}
+		}, { priority: 'high' } );
+
 		const getCommandExecuter = commandName => {
 			return ( data, cancel ) => {
 				const command = this.editor.commands.get( commandName );

+ 62 - 0
packages/ckeditor5-list/tests/list.js

@@ -116,6 +116,68 @@ describe( 'List', () => {
 		} );
 	} );
 
+	describe( 'delete key handling callback', () => {
+		it( 'should execute outdentList command on backspace key in first item of list', () => {
+			const domEvtDataStub = { preventDefault() {}, direction: 'backward' };
+
+			sinon.spy( editor, 'execute' );
+
+			setData( doc, '<listItem type="bulleted" indent="0">[]foo</listItem>' );
+
+			editor.editing.view.fire( 'delete', domEvtDataStub );
+
+			expect( editor.execute.calledWithExactly( 'outdentList' ) );
+		} );
+
+		it( 'should execute outdentList command on backspace key in first item of list', () => {
+			const domEvtDataStub = { preventDefault() {}, direction: 'backward' };
+
+			sinon.spy( editor, 'execute' );
+
+			setData( doc, '<paragraph>foo</paragraph><listItem type="bulleted" indent="0">[]foo</listItem>' );
+
+			editor.editing.view.fire( 'delete', domEvtDataStub );
+
+			expect( editor.execute.calledWithExactly( 'outdentList' ) );
+		} );
+
+		it( 'should not execute outdentList command on backspace key not in first place in list', () => {
+			const domEvtDataStub = { preventDefault() {}, direction: 'forward' };
+
+			sinon.spy( editor, 'execute' );
+
+			setData( doc, '<listItem type="bulleted" indent="0">fo[]o</listItem>' );
+
+			editor.editing.view.fire( 'delete', domEvtDataStub );
+
+			sinon.assert.notCalled( editor.execute );
+		} );
+
+		it( 'should not execute outdentList command on delete key in first item of list', () => {
+			const domEvtDataStub = { preventDefault() {}, direction: 'forward' };
+
+			sinon.spy( editor, 'execute' );
+
+			setData( doc, '<listItem type="bulleted" indent="0">[]foo</listItem>' );
+
+			editor.editing.view.fire( 'delete', domEvtDataStub );
+
+			sinon.assert.notCalled( editor.execute );
+		} );
+
+		it( 'should not execute outdentList command when selection is not collapsed', () => {
+			const domEvtDataStub = { preventDefault() {}, direction: 'backward' };
+
+			sinon.spy( editor, 'execute' );
+
+			setData( doc, '<listItem type="bulleted" indent="0">[fo]o</listItem>' );
+
+			editor.editing.view.fire( 'delete', domEvtDataStub );
+
+			sinon.assert.notCalled( editor.execute );
+		} );
+	} );
+
 	describe( 'tab key handling callback', () => {
 		let domEvtDataStub;