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

Commit

Permalink
Feature: Creating a paragraph next to the selected widget is possible…
Browse files Browse the repository at this point in the history
… using the (Shift+)Enter key (see ckeditor/ckeditor5#407).
  • Loading branch information
oleq committed Jun 13, 2018
1 parent 543422b commit 4dc91c4
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/widget.js
Expand Up @@ -154,6 +154,8 @@ export default class Widget extends Plugin {
wasHandled = this._handleArrowKeys( isForward );
} else if ( isSelectAllKeyCode( domEventData ) ) {
wasHandled = this._selectAllNestedEditableContent() || this._selectAllContent();
} else if ( keyCode === keyCodes.enter ) {
wasHandled = this._handleEnterKey( domEventData.shiftKey );
}

if ( wasHandled ) {
Expand Down Expand Up @@ -207,6 +209,7 @@ export default class Widget extends Plugin {
/**
* Handles arrow keys.
*
* @private
* @param {Boolean} isForward Set to true if arrow key should be handled in forward direction.
* @returns {Boolean|undefined} Returns `true` if keys were handled correctly.
*/
Expand Down Expand Up @@ -246,6 +249,34 @@ export default class Widget extends Plugin {
}
}

/**
* Handles the enter key, giving users and access to positions in the editable directly before
* (<kbd>Shift</kbd>+<kbd>Enter</kbd>) or after (<kbd>Enter</kbd>) the selected widget.
* It improves the UX, mainly when the widget is the first or last child of the root editable
* and there's no other way to type after or before it.
*
* @private
* @param {Boolean} isBackwards Set to true if the new paragraph is to be inserted before
* the selected widget (<kbd>Shift</kbd>+<kbd>Enter</kbd>).
* @returns {Boolean|undefined} Returns `true` if keys were handled correctly.
*/
_handleEnterKey( isBackwards ) {
const model = this.editor.model;
const modelSelection = model.document.selection;
const objectElement = modelSelection.getSelectedElement();

if ( objectElement && model.schema.isObject( objectElement ) ) {
model.change( writer => {
const paragraph = writer.createElement( 'paragraph' );

writer.insert( paragraph, objectElement, isBackwards ? 'before' : 'after' );
writer.setSelection( paragraph, 'in' );
} );

return true;
}
}

/**
* Extends the {@link module:engine/model/selection~Selection document's selection} to span the entire
* content of the nested editable if already anchored in one.
Expand Down
44 changes: 44 additions & 0 deletions tests/widget.js
Expand Up @@ -681,6 +681,50 @@ describe( 'Widget', () => {
);
} );

describe( 'enter', () => {
test(
'should insert a paragraph after the selected widget upon Enter',
'[<widget></widget>]',
keyCodes.enter,
'<widget></widget><paragraph>[]</paragraph>'
);

test(
'should insert a paragraph before the selected widget upon Shift+Enter',
'[<widget></widget>]',
{ keyCode: keyCodes.enter, shiftKey: true },
'<paragraph>[]</paragraph><widget></widget>'
);

test(
'should insert a paragraph when not a first-child of the root',
'[<widget></widget>]<paragraph>foo</paragraph>',
keyCodes.enter,
'<widget></widget><paragraph>[]</paragraph><paragraph>foo</paragraph>'
);

test(
'should insert a paragraph when not a last-child of the root',
'<paragraph>foo</paragraph>[<widget></widget>]',
{ keyCode: keyCodes.enter, shiftKey: true },
'<paragraph>foo</paragraph><paragraph>[]</paragraph><widget></widget>'
);

test(
'should insert a paragraph only when an entire widget is selected (#1)',
'<widget><nested>[foo] bar</nested></widget>',
keyCodes.enter,
'<widget><nested>[] bar</nested></widget>'
);

test(
'should insert a paragraph only when an entire widget is selected (#2)',
'<paragraph>f[oo</paragraph><widget></widget><paragraph>b]ar</paragraph>',
keyCodes.enter,
'<paragraph>f[]ar</paragraph>'
);
} );

function test( name, data, keyCodeOrMock, expected, expectedView ) {
it( name, () => {
const domEventDataMock = ( typeof keyCodeOrMock == 'object' ) ? keyCodeOrMock : {
Expand Down

0 comments on commit 4dc91c4

Please sign in to comment.