diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 81028e48a92b42..001c7cff625807 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -388,7 +388,7 @@ Insert an image to make a visual statement. ([Source](https://github.com/WordPre - **Name:** core/image - **Category:** media - **Supports:** align (center, full, left, right, wide), anchor, color (~~background~~, ~~text~~), filter (duotone), interactivity, shadow () -- **Attributes:** alt, aspectRatio, caption, height, href, id, lightbox, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width +- **Attributes:** alt, aspectRatio, blob, caption, height, href, id, lightbox, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width ## Latest Comments diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 0b0b378889070d..1191968032a7b5 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -237,7 +237,7 @@ function GalleryEdit( props ) { return ( ALLOWED_MEDIA_TYPES.some( ( mediaType ) => mediaTypeSelector?.indexOf( mediaType ) === 0 - ) || file.url?.indexOf( 'blob:' ) === 0 + ) || file.blob ); } @@ -249,9 +249,9 @@ function GalleryEdit( props ) { const imageArray = newFileUploads ? Array.from( selectedImages ).map( ( file ) => { if ( ! file.url ) { - return pickRelevantMediaFiles( { - url: createBlobURL( file ), - } ); + return { + blob: createBlobURL( file ), + }; } return file; @@ -271,9 +271,9 @@ function GalleryEdit( props ) { .filter( ( file ) => file.url || isValidFileType( file ) ) .map( ( file ) => { if ( ! file.url ) { - return pickRelevantMediaFiles( { - url: createBlobURL( file ), - } ); + return { + blob: file.blob || createBlobURL( file ), + }; } return file; @@ -307,6 +307,7 @@ function GalleryEdit( props ) { const newBlocks = newImageList.map( ( image ) => { return createBlock( 'core/image', { id: image.id, + blob: image.blob, url: image.url, caption: image.caption, alt: image.alt, diff --git a/packages/block-library/src/gallery/transforms.js b/packages/block-library/src/gallery/transforms.js index bcb1dd016c5d90..6e76cd93ef560d 100644 --- a/packages/block-library/src/gallery/transforms.js +++ b/packages/block-library/src/gallery/transforms.js @@ -223,7 +223,7 @@ const transforms = { if ( isGalleryV2Enabled() ) { const innerBlocks = files.map( ( file ) => createBlock( 'core/image', { - url: createBlobURL( file ), + blob: createBlobURL( file ), } ) ); diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 1076aad0f17982..b9d269db674621 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -9,6 +9,10 @@ "keywords": [ "img", "photo", "picture" ], "textdomain": "default", "attributes": { + "blob": { + "type": "string", + "__experimentalRole": "local" + }, "url": { "type": "string", "source": "attribute", diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 673ab44a8c28aa..df07fd0474eff1 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -56,17 +56,6 @@ export const pickRelevantMediaFiles = ( image, size ) => { return imageProps; }; -/** - * Is the URL a temporary blob URL? A blob URL is one that is used temporarily - * while the image is being uploaded and will not have an id yet allocated. - * - * @param {number=} id The id of the image. - * @param {string=} url The url of the image. - * - * @return {boolean} Is the URL a Blob URL - */ -const isTemporaryImage = ( id, url ) => ! id && isBlobURL( url ); - /** * Is the url for the image hosted externally. An externally hosted image has no * id and is not a blob url. @@ -118,9 +107,7 @@ export function ImageEdit( { align, metadata, } = attributes; - const [ temporaryURL, setTemporaryURL ] = useState( () => { - return isTemporaryImage( id, url ) ? url : undefined; - } ); + const [ temporaryURL, setTemporaryURL ] = useState( attributes.blob ); const altRef = useRef(); useEffect( () => { @@ -157,8 +144,8 @@ export function ImageEdit( { src: undefined, id: undefined, url: undefined, + blob: undefined, } ); - setTemporaryURL( undefined ); } function onSelectImage( media ) { @@ -169,7 +156,9 @@ export function ImageEdit( { id: undefined, title: undefined, caption: undefined, + blob: undefined, } ); + setTemporaryURL(); return; } @@ -179,8 +168,6 @@ export function ImageEdit( { return; } - setTemporaryURL(); - const { imageDefaultSize } = getSettings(); // Try to use the previous selected image size if its available @@ -254,24 +241,28 @@ export function ImageEdit( { mediaAttributes.href = href; setAttributes( { + blob: undefined, ...mediaAttributes, ...additionalAttributes, linkDestination, } ); + setTemporaryURL(); } function onSelectURL( newURL ) { if ( newURL !== url ) { setAttributes( { + blob: undefined, url: newURL, id: undefined, sizeSlug: getSettings().imageDefaultSize, } ); + setTemporaryURL(); } } useUploadMediaFromBlobURL( { - url, + url: temporaryURL, allowedTypes: ALLOWED_MEDIA_TYPES, onChange: onSelectImage, onError: onUploadError, @@ -292,7 +283,7 @@ export function ImageEdit( { const shadowProps = getShadowClassesAndStyles( attributes ); const classes = clsx( className, { - 'is-transient': temporaryURL, + 'is-transient': !! temporaryURL, 'is-resized': !! width || !! height, [ `size-${ sizeSlug }` ]: sizeSlug, 'has-custom-border': diff --git a/packages/block-library/src/image/transforms.js b/packages/block-library/src/image/transforms.js index a96a93640292b5..fda29a2ca2530a 100644 --- a/packages/block-library/src/image/transforms.js +++ b/packages/block-library/src/image/transforms.js @@ -159,7 +159,7 @@ const transforms = { transform( files ) { const blocks = files.map( ( file ) => { return createBlock( 'core/image', { - url: createBlobURL( file ), + blob: createBlobURL( file ), } ); } ); return blocks; diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index 2d50ff986492fe..43733d7f49a046 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -47,7 +47,6 @@ export function useUploadMediaFromBlobURL( args = {} ) { if ( hasUploadStarted.current ) { return; } - if ( ! latestArgs.current.url || ! isBlobURL( latestArgs.current.url ) diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 609e62fc7e84b2..2e7246ce9584a9 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -237,6 +237,11 @@ export function getCommentAttributes( blockType, attributes ) { return accumulator; } + // Ignore all local attributes + if ( attributeSchema.__experimentalRole === 'local' ) { + return accumulator; + } + // Ignore default value. if ( 'default' in attributeSchema && diff --git a/packages/blocks/src/api/test/serializer.js b/packages/blocks/src/api/test/serializer.js index 6cb21470f9e1fa..7fed23041daaa6 100644 --- a/packages/blocks/src/api/test/serializer.js +++ b/packages/blocks/src/api/test/serializer.js @@ -148,6 +148,30 @@ describe( 'block serializer', () => { expect( attributes ).toEqual( { fruit: 'bananas' } ); } ); + + it( 'should ingore local attributes', () => { + const attributes = getCommentAttributes( + { + attributes: { + blob: { + type: 'string', + __experimentalRole: 'local', + }, + url: { + type: 'string', + }, + }, + }, + { + blob: 'blob://false-url.com', + url: 'http://real-url.com', + } + ); + + expect( attributes ).toEqual( { + url: 'http://real-url.com', + } ); + } ); } ); describe( 'serializeAttributes()', () => {