From 25c6b5ef732842a9cf3b30305a5515c1d0bd7b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <4710635+ellatrix@users.noreply.github.com> Date: Wed, 30 Mar 2022 20:53:20 +0300 Subject: [PATCH] Partial multi-select: fix error with dead key (#39850) --- .../src/components/writing-flow/use-input.js | 29 +++++++++++++++++++ .../multi-block-selection.test.js.snap | 16 ++++++++++ .../various/multi-block-selection.test.js | 21 ++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/packages/block-editor/src/components/writing-flow/use-input.js b/packages/block-editor/src/components/writing-flow/use-input.js index 08aeb1cdccdc8a..8b9b977a993e20 100644 --- a/packages/block-editor/src/components/writing-flow/use-input.js +++ b/packages/block-editor/src/components/writing-flow/use-input.js @@ -40,6 +40,7 @@ export default function useInput() { } if ( event.keyCode === ENTER ) { + node.contentEditable = false; event.preventDefault(); if ( __unstableIsFullySelected() ) { replaceBlocks( @@ -53,6 +54,7 @@ export default function useInput() { event.keyCode === BACKSPACE || event.keyCode === DELETE ) { + node.contentEditable = false; event.preventDefault(); if ( __unstableIsFullySelected() ) { removeBlocks( getSelectedBlockClientIds() ); @@ -67,17 +69,44 @@ export default function useInput() { event.key.length === 1 && ! ( event.metaKey || event.ctrlKey ) ) { + node.contentEditable = false; if ( __unstableIsSelectionMergeable() ) { __unstableDeleteSelection( event.keyCode === DELETE ); } else { event.preventDefault(); + // Safari does not stop default behaviour with either + // event.preventDefault() or node.contentEditable = false, so + // remove the selection to stop browser manipulation. + node.ownerDocument.defaultView + .getSelection() + .removeAllRanges(); } } } + function onCompositionStart( event ) { + if ( ! hasMultiSelection() ) { + return; + } + + node.contentEditable = false; + + if ( __unstableIsSelectionMergeable() ) { + __unstableDeleteSelection(); + } else { + event.preventDefault(); + // Safari does not stop default behaviour with either + // event.preventDefault() or node.contentEditable = false, so + // remove the selection to stop browser manipulation. + node.ownerDocument.defaultView.getSelection().removeAllRanges(); + } + } + node.addEventListener( 'keydown', onKeyDown ); + node.addEventListener( 'compositionstart', onCompositionStart ); return () => { node.removeEventListener( 'keydown', onKeyDown ); + node.removeEventListener( 'compositionstart', onCompositionStart ); }; }, [] ); } diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap index df1be62cbe878f..b75df36d20904f 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap @@ -317,3 +317,19 @@ exports[`Multi-block selection should use selection direction to determine verti
3
" `; + +exports[`Multi-block selection should write over selection 1`] = ` +" +1[
+ + + +]2
+" +`; + +exports[`Multi-block selection should write over selection 2`] = ` +" +1...2
+" +`; diff --git a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js index 29004182e01e85..226a801446cf57 100644 --- a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js +++ b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js @@ -858,6 +858,27 @@ describe( 'Multi-block selection', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + it( 'should write over selection', async () => { + await clickBlockAppender(); + await page.keyboard.type( '1[' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( ']2' ); + await page.keyboard.press( 'ArrowLeft' ); + // Select everything between []. + await pressKeyWithModifier( 'shift', 'ArrowLeft' ); + await pressKeyWithModifier( 'shift', 'ArrowLeft' ); + await pressKeyWithModifier( 'shift', 'ArrowLeft' ); + + // Test setup. + expect( await getEditedPostContent() ).toMatchSnapshot(); + + // Ensure selection is in the correct place. + await page.keyboard.type( '...' ); + + // Expect a heading with "1&2" as its content. + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); + it( 'should handle Enter across blocks', async () => { await clickBlockAppender(); await page.keyboard.type( '1[' );