Skip to content

Commit

Permalink
Selection: maintain correct selection after drag-selecting outside bl…
Browse files Browse the repository at this point in the history
…ock (#58684)
  • Loading branch information
ellatrix authored Feb 5, 2024
1 parent 9cf0fc0 commit ae193eb
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,16 @@ export default function useDragSelection() {
const selection = defaultView.getSelection();

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

if (
anchorElement.contains( commonAncestorContainer )
) {
anchorElement.focus();
selection.removeAllRanges();
selection.addRange( clonedRange );
}
}
} );
Expand Down
68 changes: 68 additions & 0 deletions test/e2e/specs/editor/various/multi-block-selection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,74 @@ test.describe( 'Multi-block selection', () => {
] );
} );

test( 'should keep correct selection when dragging outside block', async ( {
page,
editor,
} ) => {
await editor.canvas
.locator( 'role=button[name="Add default block"i]' )
.click();
await page.keyboard.type( '123' );
await page.keyboard.press( 'ArrowLeft' );

const coord2 = await editor.canvas.locator( ':root' ).evaluate( () => {
const selection = window.getSelection();
const range = selection.getRangeAt( 0 );
const rect1 = range.getClientRects()[ 0 ];
const iframeOffset = window.frameElement.getBoundingClientRect();
return {
x: iframeOffset.x + rect1.x,
y: iframeOffset.y + rect1.y + rect1.height / 2,
};
} );

await page.keyboard.press( 'ArrowLeft' );

const coord1 = await editor.canvas.locator( ':root' ).evaluate( () => {
const selection = window.getSelection();
const range = selection.getRangeAt( 0 );
const rect1 = range.getClientRects()[ 0 ];
const iframeOffset = window.frameElement.getBoundingClientRect();

return {
x: iframeOffset.x + rect1.x,
y: iframeOffset.y + rect1.y + rect1.height / 2,
};
} );

const coord3Y = await editor.canvas.locator( ':root' ).evaluate( () => {
const element = document.querySelector(
'[data-type="core/paragraph"]'
);
const rect2 = element.getBoundingClientRect();
const iframeOffset = window.frameElement.getBoundingClientRect();
// Move a bit outside the paragraph, downwards.
return iframeOffset.y + rect2.y + rect2.height + 5;
} );

await page.mouse.click( coord1.x, coord1.y );
await page.mouse.down();
await page.mouse.move( coord2.x, coord2.y, { steps: 10 } );
await page.mouse.move( coord2.x, coord3Y, { steps: 10 } );
await page.mouse.up();

// Wait for:
// https://github.com/WordPress/gutenberg/blob/eb2bb1d3456ea98db74b4518e3394ed6aed9e79f/packages/block-editor/src/components/writing-flow/use-drag-selection.js#L47
await page.evaluate(
() => new Promise( window.requestAnimationFrame )
);

// "23" should be deleted.
await page.keyboard.press( 'Backspace' );

await expect.poll( editor.getBlocks ).toMatchObject( [
{
name: 'core/paragraph',
attributes: { content: '1' },
},
] );
} );

test( 'should preserve dragged selection on move', async ( {
page,
editor,
Expand Down

0 comments on commit ae193eb

Please sign in to comment.