diff --git a/blocks/image-placeholder/index.js b/blocks/image-placeholder/index.js index 9b81bdc2d8168..5a92827f0c8dc 100644 --- a/blocks/image-placeholder/index.js +++ b/blocks/image-placeholder/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { map } from 'lodash'; + /** * WordPress dependencies */ @@ -9,6 +14,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import MediaUpload from '../media-upload'; +import { rawHandler } from '../api'; /** * ImagePlaceHolder is a react component used by blocks containing user configurable images e.g: image and cover image. @@ -19,7 +25,12 @@ import MediaUpload from '../media-upload'; */ export default function ImagePlaceHolder( { className, icon, label, onSelectImage } ) { const setImage = ( [ image ] ) => onSelectImage( image ); - const dropFiles = ( files ) => mediaUpload( files, setImage ); + const onFilesDrop = ( files ) => mediaUpload( files, setImage ); + const onHTMLDrop = ( HTML ) => setImage( map( + rawHandler( { HTML, mode: 'BLOCKS' } ) + .filter( ( { name } ) => name === 'core/image' ), + 'attributes' + ) ); const uploadFromFiles = ( event ) => mediaUpload( event.target.files, setImage ); return ( { - this.dropzones.push( { element, updateState, onDrop, onFilesDrop } ); + add: ( { element, updateState, onDrop, onFilesDrop, onHTMLDrop } ) => { + this.dropzones.push( { element, updateState, onDrop, onFilesDrop, onHTMLDrop } ); }, remove: ( element ) => { this.dropzones = filter( this.dropzones, ( dropzone ) => dropzone.element !== element ); @@ -174,8 +174,15 @@ class DropZoneProvider extends Component { return; } - if ( event.dataTransfer && !! dropzone && !! dropzone.onFilesDrop ) { - dropzone.onFilesDrop( Array.prototype.slice.call( event.dataTransfer.files ), position ); + if ( event.dataTransfer && !! dropzone ) { + const files = event.dataTransfer.files; + const HTML = event.dataTransfer.getData( 'text/html' ); + + if ( files.length && dropzone.onFilesDrop ) { + dropzone.onFilesDrop( [ ...event.dataTransfer.files ], position ); + } else if ( HTML && dropzone.onHTMLDrop ) { + dropzone.onHTMLDrop( HTML, position ); + } } event.stopPropagation(); diff --git a/editor/components/block-drop-zone/index.js b/editor/components/block-drop-zone/index.js index 00e43e85372c1..d3836f32f98f7 100644 --- a/editor/components/block-drop-zone/index.js +++ b/editor/components/block-drop-zone/index.js @@ -8,7 +8,7 @@ import { reduce, get, find } from 'lodash'; * WordPress dependencies */ import { DropZone, withContext } from '@wordpress/components'; -import { getBlockTypes } from '@wordpress/blocks'; +import { getBlockTypes, rawHandler } from '@wordpress/blocks'; import { compose } from '@wordpress/element'; /** @@ -21,7 +21,13 @@ function BlockDropZone( { index, isLocked, ...props } ) { return null; } - const dropFiles = ( files, position ) => { + const getInsertPosition = ( position ) => { + if ( index !== undefined ) { + return position.y === 'top' ? index : index + 1; + } + }; + + const onDropFiles = ( files, position ) => { const transformation = reduce( getBlockTypes(), ( ret, blockType ) => { if ( ret ) { return ret; @@ -33,19 +39,26 @@ function BlockDropZone( { index, isLocked, ...props } ) { }, false ); if ( transformation ) { - let insertPosition; - if ( index !== undefined ) { - insertPosition = position.y === 'top' ? index : index + 1; - } + const insertPosition = getInsertPosition( position ); + transformation.transform( files ).then( ( blocks ) => { props.insertBlocks( blocks, insertPosition ); } ); } }; + const onHTMLDrop = ( HTML, position ) => { + const blocks = rawHandler( { HTML, mode: 'BLOCKS' } ); + + if ( blocks.length ) { + props.insertBlocks( blocks, getInsertPosition( position ) ); + } + }; + return ( ); }