From 500d8c0c02e0d7a2352dbc705ddc94f52be14641 Mon Sep 17 00:00:00 2001
From: George Mamadashvili <georgemamadashvili@gmail.com>
Date: Tue, 6 Jul 2021 20:06:17 +0400
Subject: [PATCH] Image Block: Improve "can switch to cover" check (#33095)

Check using possible block transformations
---
 packages/block-library/src/image/image.js | 83 +++++++++++------------
 1 file changed, 38 insertions(+), 45 deletions(-)

diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js
index be710aa4e523e4..100ddeeae88772 100644
--- a/packages/block-library/src/image/image.js
+++ b/packages/block-library/src/image/image.js
@@ -32,11 +32,7 @@ import {
 import { useEffect, useState, useRef } from '@wordpress/element';
 import { __, sprintf, isRTL } from '@wordpress/i18n';
 import { getPath } from '@wordpress/url';
-import {
-	createBlock,
-	getBlockType,
-	switchToBlockType,
-} from '@wordpress/blocks';
+import { createBlock, switchToBlockType } from '@wordpress/blocks';
 import { crop, overlayText, upload } from '@wordpress/icons';
 import { store as noticesStore } from '@wordpress/notices';
 import { store as coreStore } from '@wordpress/core-data';
@@ -61,27 +57,6 @@ function getFilename( url ) {
 	}
 }
 
-/**
- * Checks if the given block is registered and is in the allowed blocks list.
- *
- * @param {string}        name Block name.
- * @param {boolean|Array} list Allowed block types.
- *
- * @return {boolean}           Whether the block exists.
- */
-function checkBlockExists( name, list ) {
-	if ( ! getBlockType( name ) ) {
-		return false;
-	}
-
-	// The allowed blocks list has a boolean value so return it.
-	if ( ! Array.isArray( list ) ) {
-		return list;
-	}
-
-	return list.includes( name );
-}
-
 export default function Image( {
 	temporaryURL,
 	attributes: {
@@ -112,7 +87,6 @@ export default function Image( {
 } ) {
 	const captionRef = useRef();
 	const prevUrl = usePrevious( url );
-	const { getBlock } = useSelect( blockEditorStore );
 	const { image, multiImageSelection } = useSelect(
 		( select ) => {
 			const { getMedia } = select( coreStore );
@@ -133,21 +107,46 @@ export default function Image( {
 		[ id, isSelected ]
 	);
 	const {
-		allowedBlockTypes,
+		canInsertCover,
+		getBlock,
 		imageEditing,
 		imageSizes,
 		maxWidth,
 		mediaUpload,
-	} = useSelect( ( select ) => {
-		const { getSettings } = select( blockEditorStore );
-		return pick( getSettings(), [
-			'allowedBlockTypes',
-			'imageEditing',
-			'imageSizes',
-			'maxWidth',
-			'mediaUpload',
-		] );
-	} );
+	} = useSelect(
+		( select ) => {
+			const {
+				getBlock: _getBlock,
+				getBlockRootClientId,
+				getBlockTransformItems,
+				getSettings,
+			} = select( blockEditorStore );
+
+			const block = _getBlock( clientId );
+			const rootClientId = getBlockRootClientId( clientId );
+			const transformations = getBlockTransformItems(
+				[ block ],
+				rootClientId
+			);
+			const settings = pick( getSettings(), [
+				'imageEditing',
+				'imageSizes',
+				'maxWidth',
+				'mediaUpload',
+			] );
+
+			return {
+				...settings,
+				getBlock: _getBlock,
+				canInsertCover:
+					transformations?.length &&
+					!! transformations.find(
+						( { name } ) => name === 'core/cover'
+					),
+			};
+		},
+		[ clientId ]
+	);
 	const { replaceBlocks, toggleSelection } = useDispatch( blockEditorStore );
 	const { createErrorNotice, createSuccessNotice } = useDispatch(
 		noticesStore
@@ -166,12 +165,6 @@ export default function Image( {
 		( { name, slug } ) => ( { value: slug, label: name } )
 	);
 
-	// Check if the cover block is registered and in allowed block list.
-	const coverBlockExists = checkBlockExists(
-		'core/cover',
-		allowedBlockTypes
-	);
-
 	// 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.
@@ -326,7 +319,7 @@ export default function Image( {
 						label={ __( 'Upload external image' ) }
 					/>
 				) }
-				{ ! multiImageSelection && coverBlockExists && (
+				{ ! multiImageSelection && canInsertCover && (
 					<ToolbarButton
 						icon={ overlayText }
 						label={ __( 'Add text over image' ) }