Skip to content

Commit

Permalink
Merge pull request #15143 from ckeditor/cf/5598-autocomplete-view-esc…
Browse files Browse the repository at this point in the history
…-handling

Fix (ui): The `AutocompleteView` should not capture the Esc key press event if its result pane is hidden.
  • Loading branch information
scofalik authored Oct 10, 2023
2 parents b304ee9 + 4c4808a commit 3da2f78
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
8 changes: 8 additions & 0 deletions packages/ckeditor5-ui/src/autocomplete/autocompleteview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ export default class AutocompleteView<

// Hide the results view when the user presses the ESC key.
this.keystrokes.set( 'esc', ( evt, cancel ) => {
// Let the DOM event pass through if the focus is in the query view.
if ( !this.resultsView.isVisible ) {
return;
}

// Focus the query view first and only then close the results view. Otherwise, if the focus
// was in the results view, it will get lost.
this.queryView.focus();
this.resultsView.isVisible = false;
cancel();
} );
Expand Down
47 changes: 38 additions & 9 deletions packages/ckeditor5-ui/tests/autocomplete/autocompleteview.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,47 @@ describe( 'AutocompleteView', () => {
expect( view.resultsView._position ).to.equal( 's' );
} );

it( 'should hide the results view upon pressing esc', () => {
const keyEvtData = {
keyCode: keyCodes.esc,
preventDefault: sinon.spy(),
stopPropagation: sinon.spy()
};
describe( 'Esc key handling', () => {
it( 'should focus the #queryView and hide the #resultsView upon pressing Esc if the results view is visible', () => {
const keyEvtData = {
keyCode: keyCodes.esc,
preventDefault: sinon.spy(),
stopPropagation: sinon.spy()
};

view.resultsView.isVisible = true;
const queryFocusSpy = sinon.spy( view.queryView, 'focus' );
const resultsIsVisibleChangeSpy = sinon.spy();

view.keystrokes.press( keyEvtData );
view.resultsView.isVisible = true;
view.resultsView.on( 'change:isVisible', resultsIsVisibleChangeSpy );

expect( view.resultsView.isVisible ).to.be.false;
view.keystrokes.press( keyEvtData );

sinon.assert.calledOnce( queryFocusSpy );
sinon.assert.calledOnce( resultsIsVisibleChangeSpy );
sinon.assert.callOrder( queryFocusSpy, resultsIsVisibleChangeSpy );
expect( view.resultsView.isVisible ).to.be.false;

sinon.assert.calledOnce( keyEvtData.preventDefault );
sinon.assert.calledOnce( keyEvtData.stopPropagation );
} );

it( 'should pass the DOM event through upon pressing Esc if the #resultsView is invisible', () => {
const keyEvtData = {
keyCode: keyCodes.esc,
preventDefault: sinon.spy(),
stopPropagation: sinon.spy()
};

const queryFocusSpy = sinon.spy( view.queryView, 'focus' );

view.keystrokes.press( keyEvtData );

sinon.assert.notCalled( queryFocusSpy );
expect( view.resultsView.isVisible ).to.be.false;
sinon.assert.notCalled( keyEvtData.preventDefault );
sinon.assert.notCalled( keyEvtData.stopPropagation );
} );
} );

it( 'should hide the results upon disabling the view', () => {
Expand Down

0 comments on commit 3da2f78

Please sign in to comment.