Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions packages/components/src/drop-zone/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class DropZoneProvider extends Component {
this.toggleDraggingOverDocument.bind( this ),
200
);
this.getNewState = this.getNewState.bind( this );

this.dropZones = [];
this.dropZoneCallbacks = {
Expand Down Expand Up @@ -135,7 +136,7 @@ class DropZoneProvider extends Component {
);
}

toggleDraggingOverDocument( event, dragEventType ) {
getNewState( event, dragEventType ) {
// In some contexts, it may be necessary to capture and redirect the
// drag event (e.g. atop an `iframe`). To accommodate this, you can
// create an instance of CustomEvent with the original event specified
Expand Down Expand Up @@ -181,6 +182,18 @@ class DropZoneProvider extends Component {
position = { x: detail.clientX, y: detail.clientY };
}

return {
isDraggingOverDocument: true,
hoveredDropZone: hoveredDropZoneIndex,
position,
};
}

toggleDraggingOverDocument( event, dragEventType ) {
const newState = this.getNewState( event, dragEventType );
const { hoveredDropZone: hoveredDropZoneIndex, position } = newState;
const hoveredDropZone = this.dropZones[ hoveredDropZoneIndex ];

// Optimisation: Only update the changed dropzones
let toUpdate = [];

Expand Down Expand Up @@ -216,11 +229,6 @@ class DropZoneProvider extends Component {
} );
} );

const newState = {
isDraggingOverDocument: true,
hoveredDropZone: hoveredDropZoneIndex,
position,
};
if ( ! isShallowEqual( newState, this.state ) ) {
this.setState( newState );
}
Expand All @@ -236,8 +244,11 @@ class DropZoneProvider extends Component {
// where files dragged directly from the dock are not recognized
event.dataTransfer && event.dataTransfer.files.length; // eslint-disable-line no-unused-expressions

const { position, hoveredDropZone } = this.state;
const dragEventType = getDragEventType( event );
const { position, hoveredDropZone } = this.getNewState(
event,
dragEventType
);
const dropZone = this.dropZones[ hoveredDropZone ];
this.resetDragState();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Draggable block should drag and drop 1`] = `
"<!-- wp:paragraph -->
<p>1</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>2</p>
<!-- /wp:paragraph -->"
`;

exports[`Draggable block should drag and drop 2`] = `
"<!-- wp:paragraph -->
<p>2</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>1</p>
<!-- /wp:paragraph -->"
`;
98 changes: 98 additions & 0 deletions packages/e2e-tests/specs/editor/various/draggable-block.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* WordPress dependencies
*/
import {
getEditedPostContent,
createNewPost,
deactivatePlugin,
activatePlugin,
showBlockToolbar,
} from '@wordpress/e2e-test-utils';

describe( 'Draggable block', () => {
beforeAll( async () => {
await deactivatePlugin(
'gutenberg-test-plugin-disables-the-css-animations'
);
} );

afterAll( async () => {
await activatePlugin(
'gutenberg-test-plugin-disables-the-css-animations'
);
} );

beforeEach( async () => {
await createNewPost();
} );

it( 'should drag and drop', async () => {
await page.keyboard.press( 'Enter' );
await page.keyboard.type( '1' );
await page.keyboard.press( 'Enter' );
await page.keyboard.type( '2' );

// Confirm correct setup.
expect( await getEditedPostContent() ).toMatchSnapshot();

await showBlockToolbar();
await page.waitForSelector( '.block-editor-block-mover__drag-handle' );

const dragHandle = await page.$(
'.block-editor-block-mover__drag-handle'
);
const dragHandleRect = await dragHandle.boundingBox();
const x = dragHandleRect.x + dragHandleRect.width / 2;
const y = dragHandleRect.y + dragHandleRect.height / 2;

await page.evaluate( () => {
document.addEventListener( 'dragstart', ( event ) => {
window._dataTransfer = JSON.parse(
event.dataTransfer.getData( 'text' )
);
} );
} );

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

await page.mouse.move( x + 10, y + 10, { steps: 10 } );

// Confirm dragged state.
await page.waitForSelector( '.block-editor-block-mover__drag-clone' );

const paragraph = await page.$( '[data-type="core/paragraph"]' );

const paragraphRect = await paragraph.boundingBox();
const pX = paragraphRect.x + paragraphRect.width / 2;
const pY = paragraphRect.y + paragraphRect.height / 3;

// Move over upper side of the first paragraph.
await page.mouse.move( pX, pY, { steps: 10 } );

// Puppeteer fires the initial `dragstart` event, but no further events.
// Simulating the drop event works.
await paragraph.evaluate(
( element, clientX, clientY ) => {
const dataTransfer = new DataTransfer();
dataTransfer.setData(
'text/plain',
JSON.stringify( window._dataTransfer )
);
const event = new DragEvent( 'drop', {
bubbles: true,
clientX,
clientY,
dataTransfer,
} );
element.dispatchEvent( event );
},
pX,
pY
);

await page.mouse.up();

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