diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index b212c21aeb43f..f86ef56a24dc8 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -18,7 +18,7 @@ import { useBlockProps, store as blockEditorStore, } from '@wordpress/block-editor'; -import { useEffect, useRef } from '@wordpress/element'; +import { useEffect, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { image as icon } from '@wordpress/icons'; @@ -91,6 +91,7 @@ export function ImageEdit( { height, sizeSlug, } = attributes; + const [ temporaryURL, setTemporaryURL ] = useState(); const altRef = useRef(); useEffect( () => { @@ -125,16 +126,15 @@ export function ImageEdit( { return; } - let mediaAttributes = pickRelevantMediaFiles( media, imageDefaultSize ); - - // If the current image is temporary but an alt text was meanwhile - // written by the user, make sure the text is not overwritten. - if ( isTemporaryImage( id, url ) ) { - if ( altRef.current ) { - mediaAttributes = omit( mediaAttributes, [ 'alt' ] ); - } + if ( isBlobURL( media.url ) ) { + setTemporaryURL( media.url ); + return; } + setTemporaryURL(); + + let mediaAttributes = pickRelevantMediaFiles( media, imageDefaultSize ); + // If a caption text was meanwhile written by the user, // make sure the text is not overwritten by empty captions. if ( captionRef.current && ! get( mediaAttributes, [ 'caption' ] ) ) { @@ -255,14 +255,14 @@ export function ImageEdit( { // If an image is temporary, revoke the Blob url when it is uploaded (and is // no longer temporary). useEffect( () => { - if ( ! isTemp ) { + if ( ! temporaryURL ) { return; } return () => { - revokeBlobURL( url ); + revokeBlobURL( temporaryURL ); }; - }, [ isTemp ] ); + }, [ temporaryURL ] ); const isExternal = isExternalImage( id, url ); const src = isExternal ? url : undefined; @@ -276,7 +276,7 @@ export function ImageEdit( { ); const classes = classnames( className, { - 'is-transient': isBlobURL( url ), + 'is-transient': temporaryURL, 'is-resized': !! width || !! height, [ `size-${ sizeSlug }` ]: sizeSlug, } ); @@ -288,8 +288,9 @@ export function ImageEdit( { return (
- { url && ( + { ( temporaryURL || url ) && ( { onImageError() } @@ -427,7 +428,7 @@ export default function Image( { ); } } /> - { isBlobURL( url ) && } + { temporaryURL && } /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */ ); diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap index 18b856a57a430..feefe814ca13d 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap @@ -17,3 +17,9 @@ exports[`Image should drag and drop files into media placeholder 1`] = `
\\"\\"/
" `; + +exports[`Image should undo without broken temporary state 1`] = ` +" +
\\"\\"/
+" +`; diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js index c0838d48d4737..1acf1248f7182 100644 --- a/packages/e2e-tests/specs/editor/blocks/image.test.js +++ b/packages/e2e-tests/specs/editor/blocks/image.test.js @@ -351,4 +351,14 @@ describe( 'Image', () => { // Check if dimensions are reset. expect( await getEditedPostContent() ).toMatch( regexAfter ); } ); + + it( 'should undo without broken temporary state', async () => { + await insertBlock( 'Image' ); + const fileName = await upload( '.wp-block-image input[type="file"]' ); + await waitForImage( fileName ); + await pressKeyWithModifier( 'primary', 'z' ); + // Expect an empty image block (placeholder) rather than one with a + // broken temporary URL. + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); } );