whole_func_string: function handleUpdateImageBlocks( calypsoPort ) {
  	calypsoPort.addEventListener( 'message', onUpdateImageBlocks, false );
  	calypsoPort.start();
  
  	const imageBlocks = {
  		'core/cover': updateSingeImageBlock,
  		'core/image': updateSingeImageBlock,
  		'core/file': partialRight( updateSingeImageBlock, { url: 'href' } ),
  		'core/gallery': updateMultipleImagesBlock,
  		'core/media-text': partialRight( updateSingeImageBlock, {
  			id: 'mediaId',
  			url: 'mediaUrl',
  		} ),
  		'jetpack/tiled-gallery': updateMultipleImagesBlock,
  	};
  
  	/**
  	 * Updates all the blocks containing a given edited image.
  	 *
  	 * @param {Array} blocks Array of block objects for the current post.
  	 * @param {Object} image The edited image.
  	 * @param {number} image.id The image ID.
  	 * @param {string} image.url The new image URL.
  	 * @param {string} image.status The new image status. "deleted" or "updated" (default).
  	 * @param {number} [image.transientId] The temporary ID assigned to uploading image.
  	 */
  	function updateImageBlocks( blocks, image ) {
  		forEach( blocks, block => {
  			if ( imageBlocks[ block.name ] ) {
  				imageBlocks[ block.name ]( block, image );
  			}
  			if ( block.innerBlocks.length ) {
  				updateImageBlocks( block.innerBlocks, image );
  			}
  		} );
  	}
  
  	function preloadImage( imageUrl ) {
  		return new Promise( ( resolve, reject ) => {
  			const preloadedImage = new Image();
  			preloadedImage.src = imageUrl;
  			preloadedImage.onload = resolve;
  			preloadedImage.onerror = reject;
  		} );
  	}
  
  	function updateSingeImageBlock( block, image, attrNames ) {
  		const blockImageId = get( block, 'attributes.id' );
  		if ( blockImageId !== image.id && blockImageId !== image.transientId ) {
  			return;
  		}
  		attrNames = { ...attrNames, id: 'id', url: 'url' };
  
  		if ( 'deleted' === image.status ) {
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.id ]: undefined,
  				[ attrNames.url ]: undefined,
  			} );
  			return;
  		}
  
  		preloadImage( image.url ).then( () => {
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.id ]: image.id,
  				[ attrNames.url ]: image.url,
  			} );
  		} );
  	}
  
  	function updateMultipleImagesBlock( block, image, attrNames ) {
  		attrNames = { ...attrNames, id: 'id', url: 'url', images: 'images' };
  		const currentImages = get( block, [ 'attributes', attrNames.images ] );
  		let updatedImages = [];
  
  		if ( 'deleted' === image.status ) {
  			updatedImages = filter( currentImages, currentImage => {
  				return currentImage.id !== image.id && currentImage.id !== image.transientId;
  			} );
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.images ]: updatedImages,
  			} );
  			return;
  		}
  
  		preloadImage( image.url ).then( () => {
  			updatedImages = map( currentImages, currentImage => {
  				const currentImageId = parseInt( currentImage.id, 10 );
  				if ( currentImageId !== image.id && currentImageId !== image.transientId ) {
  					return currentImage;
  				}
  				return {
  					[ attrNames.id ]: image.id,
  					[ attrNames.url ]: image.url,
  				};
  			} );
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.images ]: updatedImages,
  			} );
  		} );
  	}
  
  	// To update the featured image preview we need to manually modify the image in the `core` state.
  	// Though, there is no direct mechanism to also invalidate its cache and re-render the preview.
  	// As a workaround, we call `receiveEntityRecords`, normally used to update the state after a fetch,
  	// which has a handy `invalidateCache` parameter that does exactly what we need.
  	function updateFeaturedImagePreview( image ) {
  		const currentImageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' );
  		if ( currentImageId !== image.id ) {
  			return;
  		}
  		preloadImage( image.url ).then( () => {
  			const currentImage = select( 'core' ).getMedia( currentImageId );
  			const updatedImage = {
  				...currentImage,
  				media_details: {
  					height: image.height,
  					width: image.width,
  				},
  				source_url: image.url,
  			};
  			dispatch( 'core' ).receiveEntityRecords( 'root', 'media', [ updatedImage ], null, true );
  		} );
  	}
  
  	function onUpdateImageBlocks( message ) {
  		const action = get( message, 'data.action' );
  		if ( action !== 'updateImageBlocks' ) {
  			return;
  		}
  		const image = get( message, 'data.payload' );
  		updateImageBlocks( select( 'core/editor' ).getBlocks(), image );
  		updateFeaturedImagePreview( image );
  	}
  }
func_code_string: function handleUpdateImageBlocks( calypsoPort ) {
  	calypsoPort.addEventListener( 'message', onUpdateImageBlocks, false );
  	calypsoPort.start();
  
  	const imageBlocks = {
  		'core/cover': updateSingeImageBlock,
  		'core/image': updateSingeImageBlock,
  		'core/file': partialRight( updateSingeImageBlock, { url: 'href' } ),
  		'core/gallery': updateMultipleImagesBlock,
  		'core/media-text': partialRight( updateSingeImageBlock, {
  			id: 'mediaId',
  			url: 'mediaUrl',
  		} ),
  		'jetpack/tiled-gallery': updateMultipleImagesBlock,
  	};
  
  	/**
  	 * Updates all the blocks containing a given edited image.
  	 *
  	 * @param {Array} blocks Array of block objects for the current post.
  	 * @param {Object} image The edited image.
  	 * @param {number} image.id The image ID.
  	 * @param {string} image.url The new image URL.
  	 * @param {string} image.status The new image status. "deleted" or "updated" (default).
  	 * @param {number} [image.transientId] The temporary ID assigned to uploading image.
  	 */
  	function updateImageBlocks( blocks, image ) {
  		forEach( blocks, block => {
  			if ( imageBlocks[ block.name ] ) {
  				imageBlocks[ block.name ]( block, image );
  			}
  			if ( block.innerBlocks.length ) {
  				updateImageBlocks( block.innerBlocks, image );
  			}
  		} );
  	}
  
  	function preloadImage( imageUrl ) {
  		return new Promise( ( resolve, reject ) => {
  			const preloadedImage = new Image();
  			preloadedImage.src = imageUrl;
  			preloadedImage.onload = resolve;
  			preloadedImage.onerror = reject;
  		} );
  	}
  
  	function updateSingeImageBlock( block, image, attrNames ) {
  		const blockImageId = get( block, 'attributes.id' );
  		if ( blockImageId !== image.id && blockImageId !== image.transientId ) {
  			return;
  		}
  		attrNames = { ...attrNames, id: 'id', url: 'url' };
  
  		if ( 'deleted' === image.status ) {
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.id ]: undefined,
  				[ attrNames.url ]: undefined,
  			} );
  			return;
  		}
  
  		preloadImage( image.url ).then( () => {
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.id ]: image.id,
  				[ attrNames.url ]: image.url,
  			} );
  		} );
  	}
  
  	function updateMultipleImagesBlock( block, image, attrNames ) {
  		attrNames = { ...attrNames, id: 'id', url: 'url', images: 'images' };
  		const currentImages = get( block, [ 'attributes', attrNames.images ] );
  		let updatedImages = [];
  
  		if ( 'deleted' === image.status ) {
  			updatedImages = filter( currentImages, currentImage => {
  				return currentImage.id !== image.id && currentImage.id !== image.transientId;
  			} );
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.images ]: updatedImages,
  			} );
  			return;
  		}
  
  		preloadImage( image.url ).then( () => {
  			updatedImages = map( currentImages, currentImage => {
  				const currentImageId = parseInt( currentImage.id, 10 );
  				if ( currentImageId !== image.id && currentImageId !== image.transientId ) {
  					return currentImage;
  				}
  				return {
  					[ attrNames.id ]: image.id,
  					[ attrNames.url ]: image.url,
  				};
  			} );
  			dispatch( 'core/editor' ).updateBlockAttributes( block.clientId, {
  				[ attrNames.images ]: updatedImages,
  			} );
  		} );
  	}
  
  	// To update the featured image preview we need to manually modify the image in the `core` state.
  	// Though, there is no direct mechanism to also invalidate its cache and re-render the preview.
  	// As a workaround, we call `receiveEntityRecords`, normally used to update the state after a fetch,
  	// which has a handy `invalidateCache` parameter that does exactly what we need.
  	function updateFeaturedImagePreview( image ) {
  		const currentImageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' );
  		if ( currentImageId !== image.id ) {
  			return;
  		}
  		preloadImage( image.url ).then( () => {
  			const currentImage = select( 'core' ).getMedia( currentImageId );
  			const updatedImage = {
  				...currentImage,
  				media_details: {
  					height: image.height,
  					width: image.width,
  				},
  				source_url: image.url,
  			};
  			dispatch( 'core' ).receiveEntityRecords( 'root', 'media', [ updatedImage ], null, true );
  		} );
  	}
  
  	function onUpdateImageBlocks( message ) {
  		const action = get( message, 'data.action' );
  		if ( action !== 'updateImageBlocks' ) {
  			return;
  		}
  		const image = get( message, 'data.payload' );
  		updateImageBlocks( select( 'core/editor' ).getBlocks(), image );
  		updateFeaturedImagePreview( image );
  	}
  }
func_documentation_string: Listens for image changes or removals happening in the Media Modal,
  and updates accordingly all blocks containing them.
  
  @param {MessagePort} calypsoPort Port used for communication with parent frame.