@wordpress/block-library
Version:
Block library for the WordPress editor.
8 lines (7 loc) • 7.76 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/html/edit.js"],
"sourcesContent": ["import { __ } from '@wordpress/i18n';\nimport { useEffect, useState } from '@wordpress/element';\nimport {\n\tBlockControls,\n\tBlockIcon,\n\tInspectorControls,\n\tuseBlockProps,\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\nimport { parse, serialize, getBlockContent } from '@wordpress/blocks';\nimport { useSelect, useDispatch, useRegistry } from '@wordpress/data';\nimport deprecated from '@wordpress/deprecated';\nimport {\n\tToolbarButton,\n\tToolbarGroup,\n\tPlaceholder,\n\tButton,\n\t__experimentalVStack as VStack,\n} from '@wordpress/components';\nimport { code } from '@wordpress/icons';\nimport { unlock } from '../lock-unlock';\nimport HTMLEditModal from './modal';\n\nconst { InnerContent } = unlock( blockEditorPrivateApis );\n\nexport default function HTMLEdit( { clientId, attributes } ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tconst registry = useRegistry();\n\tconst { updateBlock, replaceInnerBlocks } = useDispatch( blockEditorStore );\n\tconst content = useSelect(\n\t\t( select ) => {\n\t\t\tconst block = select( blockEditorStore ).getBlock( clientId );\n\t\t\treturn block ? getBlockContent( block ) : '';\n\t\t},\n\t\t[ clientId ]\n\t);\n\tconst blockProps = useBlockProps( {\n\t\tclassName: 'block-library-html__edit',\n\t} );\n\n\t// Re-parse the edited content: static HTML becomes the block's\n\t// `innerContent` fragments and `<!-- wp:* -->` delimited segments become\n\t// inner blocks mounted at their positions within the static markup.\n\tconst onUpdate = ( nextContent ) => {\n\t\tif ( nextContent === content ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst [ parsedBlock ] = parse(\n\t\t\t`<!-- wp:html -->\\n${ nextContent }\\n<!-- /wp:html -->`\n\t\t);\n\t\tconst nextInnerBlocks = parsedBlock?.innerBlocks ?? [];\n\t\tconst prevInnerBlocks = registry\n\t\t\t.select( blockEditorStore )\n\t\t\t.getBlocks( clientId );\n\t\t// Keep the existing inner blocks, and thereby their client IDs and\n\t\t// selection, when their markup is unchanged — e.g. when only the\n\t\t// surrounding static HTML was edited.\n\t\tconst innerBlocksUnchanged =\n\t\t\tprevInnerBlocks.length === nextInnerBlocks.length &&\n\t\t\tprevInnerBlocks.every(\n\t\t\t\t( block, index ) =>\n\t\t\t\t\tserialize( block ) === serialize( nextInnerBlocks[ index ] )\n\t\t\t);\n\n\t\tregistry.batch( () => {\n\t\t\tupdateBlock( clientId, {\n\t\t\t\tinnerContent:\n\t\t\t\t\tparsedBlock?.innerContent ??\n\t\t\t\t\t( nextContent ? [ nextContent ] : [] ),\n\t\t\t} );\n\t\t\tif ( ! innerBlocksUnchanged ) {\n\t\t\t\treplaceInnerBlocks( clientId, nextInnerBlocks, false );\n\t\t\t}\n\t\t} );\n\t};\n\n\t// Migrate the deprecated `content` attribute. The block's markup now lives\n\t// in its inner content, but a block created via `createBlock( 'core/html',\n\t// { content } )` still arrives with a `content` attribute. As soon as it\n\t// loads, move that markup into the block's inner content and clear the\n\t// attribute.\n\tuseEffect( () => {\n\t\tif ( ! attributes.content ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdeprecated( 'The content attribute on the Custom HTML block', {\n\t\t\tsince: '7.1',\n\t\t\talternative: 'inner content',\n\t\t} );\n\n\t\tupdateBlock( clientId, {\n\t\t\tattributes: { content: undefined },\n\t\t\tinnerContent: [ attributes.content ],\n\t\t} );\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ attributes.content ] );\n\n\t// Show placeholder when content is empty\n\tif ( ! content?.trim() ) {\n\t\treturn (\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<Placeholder\n\t\t\t\t\ticon={ <BlockIcon icon={ code } /> }\n\t\t\t\t\tlabel={ __( 'Custom HTML' ) }\n\t\t\t\t\tinstructions={ __(\n\t\t\t\t\t\t'Add custom HTML code and preview how it looks.'\n\t\t\t\t\t) }\n\t\t\t\t>\n\t\t\t\t\t<Button\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Edit HTML' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t</Placeholder>\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<HTMLEditModal\n\t\t\t\t\t\tonRequestClose={ () => setIsModalOpen( false ) }\n\t\t\t\t\t\tcontent={ content }\n\t\t\t\t\t\tonUpdate={ onUpdate }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div { ...blockProps }>\n\t\t\t<BlockControls>\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<ToolbarButton onClick={ () => setIsModalOpen( true ) }>\n\t\t\t\t\t\t{ __( 'Edit code' ) }\n\t\t\t\t\t</ToolbarButton>\n\t\t\t\t</ToolbarGroup>\n\t\t\t</BlockControls>\n\t\t\t<InspectorControls>\n\t\t\t\t<VStack className=\"block-library-html__edit-code\" expanded>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tclassName=\"block-library-html__edit-code-button\"\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Edit code' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t</VStack>\n\t\t\t</InspectorControls>\n\t\t\t<InnerContent clientId={ clientId } />\n\t\t\t{ isModalOpen && (\n\t\t\t\t<HTMLEditModal\n\t\t\t\t\tonRequestClose={ () => setIsModalOpen( false ) }\n\t\t\t\t\tcontent={ content }\n\t\t\t\t\tonUpdate={ onUpdate }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n"],
"mappings": "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",
"names": []
}