import { localizeUrl } from '@automattic/i18n-utils';
import { createInterpolateElement } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import { JSXElementConstructor, ReactElement } from 'react';
import blockInfoMapping, {
blockInfoWithVariations,
childrenBlockInfoWithDifferentUrl,
} from './block-links-map';
import DescriptionSupportLink from './inline-support-link';
declare global {
interface Window {
wpcomBlockDescriptionLinksLocale: string;
}
}
const createLocalizedDescriptionWithLearnMore = (
title: string,
description: string | ReactElement< string | JSXElementConstructor< any > >,
url: string,
postId: number
) => {
const localizedUrl = localizeUrl( url, window.wpcomBlockDescriptionLinksLocale );
return createInterpolateElement( '', {
InlineSupportLink: (
{ description }
),
} );
};
const processedBlocks: { [ key: string ]: true } = {};
const addBlockSupportLinks = (
settings: {
variations: Array< {
description: string | ReactElement< string | JSXElementConstructor< any > >;
name: string;
title: string;
} >;
} & {
[ key: string ]: string | ReactElement< string | JSXElementConstructor< any > >;
},
name: string
) => {
// If block has a parent, use the parents name in the switch. This will apply the link to all nested blocks.
// The exception is "post content" block because it's used to allow blocks like "more" and "jetpack/paywall" only in post content areas & post editor
// `parent` is actually an array of strings, so converting to string is going to join multiple blocks together, making the method buggy.
const parentName = settings?.parent?.toString();
const isChild = parentName && parentName !== 'core/post-content';
const blockName = isChild ? parentName : name;
/**
* This is needed because the `blocks.registerBlockType` filter is also triggered for deprecations.
*
* When the block has deprecations, this filter is triggered multiple times, resulting the Learn more link being appended multiple times.
*/
if ( processedBlocks[ name ] ) {
return settings;
}
processedBlocks[ name ] = true;
const additonalDescLink =
childrenBlockInfoWithDifferentUrl[ name ]?.link || blockInfoMapping[ blockName ]?.link;
const additionalDescPostId =
childrenBlockInfoWithDifferentUrl[ name ]?.postId || blockInfoMapping[ blockName ]?.postId;
/**
* Some elements are children, but have their own url for Learn More, and we want to show those.
*/
if ( additonalDescLink && additionalDescPostId ) {
settings.description = createLocalizedDescriptionWithLearnMore(
String( settings.title ),
settings.description,
additonalDescLink,
additionalDescPostId
);
}
if (
blockInfoWithVariations[ name ] &&
settings.variations &&
Array.isArray( settings.variations )
) {
settings.variations = settings.variations.map(
( variation: {
title: string;
name: string;
description: string | ReactElement< string | JSXElementConstructor< any > >;
} ) => {
const link = blockInfoWithVariations[ name ][ variation.name ]?.link;
const postId = blockInfoWithVariations[ name ][ variation.name ]?.postId;
if ( ! link ) {
return variation;
}
variation.description = createLocalizedDescriptionWithLearnMore(
variation.title,
variation.description,
link,
postId
);
return variation;
}
);
}
return settings;
};
addFilter(
'blocks.registerBlockType',
'full-site-editing/add-block-support-link',
addBlockSupportLinks
);