From 0db02ea7a1232d6730174fbbc5f673b74d190f68 Mon Sep 17 00:00:00 2001 From: Ella van Durpe Date: Thu, 2 Jul 2020 14:03:43 +0300 Subject: [PATCH] Only show button if image can bee uploaded --- packages/block-library/src/image/edit.js | 2 +- packages/block-library/src/image/image.js | 66 ++++++++++++----------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index a61b2d92fbdd9c..a1205b8b91bd42 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -65,7 +65,7 @@ const isTemporaryImage = ( id, url ) => ! id && isBlobURL( url ); * * @return {boolean} Is the url an externally hosted url? */ -const isExternalImage = ( id, url ) => url && ! id && ! isBlobURL( url ); +export const isExternalImage = ( id, url ) => url && ! id && ! isBlobURL( url ); export function ImageEdit( { attributes, diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 86634fb78c1a5d..87fd783ae5e63c 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -40,6 +40,7 @@ import { crop, upload } from '@wordpress/icons'; import { createUpgradedEmbedBlock } from '../embed/util'; import useClientWidth from './use-client-width'; import ImageEditor from './image-editor'; +import { isExternalImage } from './edit'; /** * Module constants @@ -106,6 +107,7 @@ export default function Image( { const isWideAligned = includes( [ 'wide', 'full' ], align ); const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} ); const [ isEditingImage, setIsEditingImage ] = useState( false ); + const [ externalBlob, setExternalBlob ] = useState(); const clientWidth = useClientWidth( containerRef, [ align ] ); const isResizable = ! isWideAligned && isLargeViewport; const imageSizeOptions = map( @@ -121,6 +123,20 @@ export default function Image( { } }, [ isSelected ] ); + // If an image is externally hosted, try to fetch the image data. This may + // fail if the image host doesn't allow CORS with the domain. If it works, + // we can enable a button in the toolbar to upload the image. + useEffect( () => { + if ( ! isExternalImage( id, url ) || ! isSelected || externalBlob ) { + return; + } + + window + .fetch( url ) + .then( ( response ) => response.blob() ) + .then( ( blob ) => setExternalBlob( blob ) ); + }, [ id, url, isSelected, externalBlob ] ); + function onResizeStart() { toggleSelection( false ); } @@ -183,37 +199,25 @@ export default function Image( { } function uploadExternal() { - window - .fetch( url ) - .then( ( response ) => response.blob() ) - .then( ( blob ) => { - mediaUpload( { - filesList: [ blob ], - onFileChange( [ img ] ) { - onSelectImage( img ); - - if ( isBlobURL( img.url ) ) { - return; - } - - createSuccessNotice( __( 'Image uploaded.' ), { - type: 'snackbar', - } ); - }, - allowedTypes: ALLOWED_MEDIA_TYPES, - onError( message ) { - createErrorNotice( message, { type: 'snackbar' } ); - }, + mediaUpload( { + filesList: [ externalBlob ], + onFileChange( [ img ] ) { + onSelectImage( img ); + + if ( isBlobURL( img.url ) ) { + return; + } + + setExternalBlob(); + createSuccessNotice( __( 'Image uploaded.' ), { + type: 'snackbar', } ); - } ) - .catch( () => { - createErrorNotice( - __( - 'The image host doesn’t allow access from a script. Please download and upload the image manually.' - ), - { type: 'snackbar' } - ); - } ); + }, + allowedTypes: ALLOWED_MEDIA_TYPES, + onError( message ) { + createErrorNotice( message, { type: 'snackbar' } ); + }, + } ); } useEffect( () => { @@ -250,7 +254,7 @@ export default function Image( { /> ) } - { ! id && ( + { externalBlob && (