Skip to content

Commit

Permalink
Merge pull request #13797 from ckeditor/ck/13321
Browse files Browse the repository at this point in the history
Fix (enter): Pressing Shift+Enter in Safari should insert <br> instead of splitting block. Closes #13321.
  • Loading branch information
arkflpc authored Apr 3, 2023
2 parents 7e7cb5b + cdb17cd commit 90445f8
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
3 changes: 2 additions & 1 deletion packages/ckeditor5-enter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"main": "src/index.ts",
"dependencies": {
"@ckeditor/ckeditor5-core": "^36.0.1",
"@ckeditor/ckeditor5-engine": "^36.0.1"
"@ckeditor/ckeditor5-engine": "^36.0.1",
"@ckeditor/ckeditor5-utils": "^36.0.1"
},
"devDependencies": {
"@ckeditor/ckeditor5-basic-styles": "^36.0.1",
Expand Down
19 changes: 17 additions & 2 deletions packages/ckeditor5-enter/src/enterobserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import {
BubblingEventInfo,
type View,
type ViewDocumentInputEvent,
type BubblingEvent
type BubblingEvent,
type ViewDocumentKeyDownEvent
} from '@ckeditor/ckeditor5-engine';

import { env } from '@ckeditor/ckeditor5-utils';

const ENTER_EVENT_TYPES: Record<string, { isSoft: boolean }> = {
insertParagraph: { isSoft: false },
insertLineBreak: { isSoft: true }
Expand All @@ -32,14 +35,26 @@ export default class EnterObserver extends Observer {
super( view );

const doc = this.document;
let shiftPressed = false;

doc.on<ViewDocumentKeyDownEvent>( 'keydown', ( evt, data ) => {
shiftPressed = data.shiftKey;
} );

doc.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, data ) => {
if ( !this.isEnabled ) {
return;
}

let inputType = data.inputType;

// See https://github.com/ckeditor/ckeditor5/issues/13321.
if ( env.isSafari && shiftPressed && inputType == 'insertParagraph' ) {
inputType = 'insertLineBreak';
}

const domEvent = data.domEvent;
const enterEventSpec = ENTER_EVENT_TYPES[ data.inputType ];
const enterEventSpec = ENTER_EVENT_TYPES[ inputType ];

if ( !enterEventSpec ) {
return;
Expand Down
53 changes: 53 additions & 0 deletions packages/ckeditor5-enter/tests/enterobserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import EnterObserver from '../src/enterobserver';
import createViewRoot from '@ckeditor/ckeditor5-engine/tests/view/_utils/createroot';
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
import { fireBeforeInputDomEvent } from '@ckeditor/ckeditor5-typing/tests/_utils/utils';
import { getCode, env } from '@ckeditor/ckeditor5-utils';

describe( 'EnterObserver', () => {
let view, viewDocument, enterSpy;
Expand Down Expand Up @@ -84,6 +85,49 @@ describe( 'EnterObserver', () => {
sinon.assert.notCalled( enterSpy );
} );

// See https://github.com/ckeditor/ckeditor5/issues/13321.
it( 'should handle the insertParagraph input type and fire the soft enter event if shift key is pressed in Safari', () => {
sinon.stub( env, 'isSafari' ).value( true );

fireKeyEvent( 'enter', { shiftKey: true } );

fireBeforeInputDomEvent( domRoot, {
inputType: 'insertParagraph'
} );

sinon.assert.calledOnce( enterSpy );
sinon.assert.calledWithMatch( enterSpy, {}, { isSoft: true } );
expect( enterSpy.firstCall.args[ 1 ] ).to.have.property( 'isSoft', true );

// Verify if the effect is not persistent.
fireKeyEvent( 'enter', { shiftKey: false } );

fireBeforeInputDomEvent( domRoot, {
inputType: 'insertParagraph'
} );

sinon.assert.calledTwice( enterSpy );
expect( enterSpy.firstCall.args[ 1 ] ).to.have.property( 'isSoft', true );
expect( enterSpy.secondCall.args[ 1 ] ).to.have.property( 'isSoft', false );
} );

// See https://github.com/ckeditor/ckeditor5/issues/13321.
it( 'should handle the insertParagraph input type and fire the enter event if shift key was pressed before in Safari', () => {
sinon.stub( env, 'isSafari' ).value( true );

fireKeyEvent( 'shift', { shiftKey: true }, 'keydown' );
fireKeyEvent( 'shift', { shiftKey: false }, 'keyup' );
fireKeyEvent( 'enter', { shiftKey: false }, 'keydown' );

fireBeforeInputDomEvent( domRoot, {
inputType: 'insertParagraph'
} );

sinon.assert.calledOnce( enterSpy );
sinon.assert.calledWithMatch( enterSpy, {}, { isSoft: false } );
expect( enterSpy.firstCall.args[ 1 ] ).to.have.property( 'isSoft', false );
} );

it( 'should never preventDefault() the beforeinput event', () => {
let interceptedEventData;

Expand Down Expand Up @@ -136,4 +180,13 @@ describe( 'EnterObserver', () => {
view.getObserver( EnterObserver ).stopObserving();
} ).to.not.throw();
} );

function fireKeyEvent( key, options, type = 'keydown' ) {
viewDocument.fire( type, {
keyCode: getCode( key ),
preventDefault: () => {},
domTarget: document.body,
...options
} );
}
} );

0 comments on commit 90445f8

Please sign in to comment.