Skip to content

Commit

Permalink
Multi select: keep selection after move (#19784)
Browse files Browse the repository at this point in the history
* Multi select: keep selection after move

* Add e2e test

* Change e2e test

* Address feedback

* Fix snapshots
  • Loading branch information
ellatrix authored Jan 22, 2020
1 parent 59ed771 commit 938fb55
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export default function useMultiSelection( ref ) {
selectedBlockClientId,
] );

const onSelectionChange = useCallback( () => {
const onSelectionChange = useCallback( ( { isSelectionEnd } ) => {
const selection = window.getSelection();

// If no selection is found, end multi selection.
Expand All @@ -156,9 +156,27 @@ export default function useMultiSelection( ref ) {
}

const clientId = getBlockClientId( selection.focusNode );
const isSingularSelection = startClientId.current === clientId;

if ( startClientId.current === clientId ) {
if ( isSingularSelection ) {
selectBlock( clientId );

// If the selection is complete (on mouse up), and no multiple
// blocks have been selected, set focus back to the anchor element
// if the anchor element contains the selection. Additionally, rich
// text elements that were previously disabled can now be enabled
// again.
if ( isSelectionEnd ) {
toggleRichText( ref.current, true );

if ( selection.rangeCount ) {
const { commonAncestorContainer } = selection.getRangeAt( 0 );

if ( anchorElement.current.contains( commonAncestorContainer ) ) {
anchorElement.current.focus();
}
}
}
} else {
const startPath = [ ...getBlockParents( startClientId.current ), startClientId.current ];
const endPath = [ ...getBlockParents( clientId ), clientId ];
Expand All @@ -178,21 +196,8 @@ export default function useMultiSelection( ref ) {
// The browser selection won't have updated yet at this point, so wait
// until the next animation frame to get the browser selection.
rafId.current = window.requestAnimationFrame( () => {
onSelectionChange();
onSelectionChange( { isSelectionEnd: true } );
stopMultiSelect();
toggleRichText( ref.current, true );

const selection = window.getSelection();

// If the anchor element contains the selection, set focus back to
// the anchor element.
if ( selection.rangeCount ) {
const { commonAncestorContainer } = selection.getRangeAt( 0 );

if ( anchorElement.current.contains( commonAncestorContainer ) ) {
anchorElement.current.focus();
}
}
} );
}, [ onSelectionChange, stopMultiSelect ] );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ exports[`Multi-block selection should only trigger multi-selection when at the e
<!-- /wp:paragraph -->"
`;

exports[`Multi-block selection should preserve dragged selection on move 1`] = `
"<!-- wp:paragraph -->
<p>2</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>3</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>1</p>
<!-- /wp:paragraph -->"
`;

exports[`Multi-block selection should return original focus after failed multi selection attempt 1`] = `
"<!-- wp:paragraph -->
<p>2</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
pressKeyWithModifier,
pressKeyTimes,
getEditedPostContent,
clickBlockToolbarButton,
} from '@wordpress/e2e-test-utils';

async function getSelectedFlatIndices() {
Expand Down Expand Up @@ -408,4 +409,44 @@ describe( 'Multi-block selection', () => {

expect( await getEditedPostContent() ).toMatchSnapshot();
} );

it( 'should preserve dragged selection on move', async () => {
await clickBlockAppender();
await page.keyboard.type( '1' );
await page.keyboard.press( 'Enter' );
await page.keyboard.type( '2' );
await page.keyboard.press( 'Enter' );
await page.keyboard.type( '3' );

const [ coord1, coord2 ] = await page.evaluate( () => {
const elements = Array.from( document.querySelectorAll( '.wp-block-paragraph' ) );
const rect1 = elements[ 2 ].getBoundingClientRect();
const rect2 = elements[ 1 ].getBoundingClientRect();
return [
{
x: rect1.x + ( rect1.width / 2 ),
y: rect1.y + ( rect1.height / 2 ),
},
{
x: rect2.x + ( rect2.width / 2 ),
y: rect2.y + ( rect2.height / 2 ),
},
];
} );

await page.mouse.move( coord1.x, coord1.y );
await page.mouse.down();
await page.mouse.move( coord2.x, coord2.y );
await page.mouse.up();

await testNativeSelection();
expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );

await clickBlockToolbarButton( 'Move up' );

await testNativeSelection();
expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );

expect( await getEditedPostContent() ).toMatchSnapshot();
} );
} );

0 comments on commit 938fb55

Please sign in to comment.