UNPKG

@wordpress/block-library

Version:
224 lines (222 loc) 6.72 kB
/** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { InspectorControls, useBlockProps, useInnerBlocksProps, RecursionProvider, useHasRecursion, Warning, privateApis as blockEditorPrivateApis, __experimentalUseBlockPreview as useBlockPreview } from '@wordpress/block-editor'; import { parse } from '@wordpress/blocks'; import { useEntityProp, useEntityBlockEditor, store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; /** * Internal dependencies */ import { useCanEditEntity } from '../utils/hooks'; import { unlock } from '../lock-unlock'; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; const { HTMLElementControl } = unlock(blockEditorPrivateApis); function ReadOnlyContent({ parentLayout, layoutClassNames, userCanEdit, postType, postId, tagName: TagName = 'div' }) { const [,, content] = useEntityProp('postType', postType, 'content', postId); const blockProps = useBlockProps({ className: layoutClassNames }); const blocks = useMemo(() => { return content?.raw ? parse(content.raw) : []; }, [content?.raw]); const blockPreviewProps = useBlockPreview({ blocks, props: blockProps, layout: parentLayout }); if (userCanEdit) { /* * Rendering the block preview using the raw content blocks allows for * block support styles to be generated and applied by the editor. * * The preview using the raw blocks can only be presented to users with * edit permissions for the post to prevent potential exposure of private * block content. */ return /*#__PURE__*/_jsx("div", { ...blockPreviewProps }); } return content?.protected ? /*#__PURE__*/_jsx(TagName, { ...blockProps, children: /*#__PURE__*/_jsx(Warning, { children: __('This content is password protected.') }) }) : /*#__PURE__*/_jsx(TagName, { ...blockProps, dangerouslySetInnerHTML: { __html: content?.rendered } }); } function EditableContent({ context = {}, tagName: TagName = 'div' }) { const { postType, postId } = context; const [blocks, onInput, onChange] = useEntityBlockEditor('postType', postType, { id: postId }); const entityRecord = useSelect(select => { return select(coreStore).getEntityRecord('postType', postType, postId); }, [postType, postId]); const hasInnerBlocks = !!entityRecord?.content?.raw || blocks?.length; const initialInnerBlocks = [['core/paragraph']]; const props = useInnerBlocksProps(useBlockProps({ className: 'entry-content' }), { value: blocks, onInput, onChange, template: !hasInnerBlocks ? initialInnerBlocks : undefined }); return /*#__PURE__*/_jsx(TagName, { ...props }); } function Content(props) { const { context: { queryId, postType, postId } = {}, layoutClassNames, tagName } = props; const userCanEdit = useCanEditEntity('postType', postType, postId); if (userCanEdit === undefined) { return null; } const isDescendentOfQueryLoop = Number.isFinite(queryId); const isEditable = userCanEdit && !isDescendentOfQueryLoop; return isEditable ? /*#__PURE__*/_jsx(EditableContent, { ...props }) : /*#__PURE__*/_jsx(ReadOnlyContent, { parentLayout: props.parentLayout, layoutClassNames: layoutClassNames, userCanEdit: userCanEdit, postType: postType, postId: postId, tagName: tagName }); } function Placeholder({ layoutClassNames }) { const blockProps = useBlockProps({ className: layoutClassNames }); return /*#__PURE__*/_jsxs("div", { ...blockProps, children: [/*#__PURE__*/_jsx("p", { children: __('This is the Content block, it will display all the blocks in any single post or page.') }), /*#__PURE__*/_jsx("p", { children: __('That might be a simple arrangement like consecutive paragraphs in a blog post, or a more elaborate composition that includes image galleries, videos, tables, columns, and any other block types.') }), /*#__PURE__*/_jsx("p", { children: __('If there are any Custom Post Types registered at your site, the Content block can display the contents of those entries as well.') })] }); } function RecursionError() { const blockProps = useBlockProps(); return /*#__PURE__*/_jsx("div", { ...blockProps, children: /*#__PURE__*/_jsx(Warning, { children: __('Block cannot be rendered inside itself.') }) }); } /** * Render inspector controls for the PostContent block. * * @param {Object} props Component props. * @param {string} props.tagName The HTML tag name. * @param {Function} props.onSelectTagName onChange function for the SelectControl. * @param {string} props.clientId The client ID of the current block. * * @return {JSX.Element} The control group. */ function PostContentEditControls({ tagName, onSelectTagName, clientId }) { return /*#__PURE__*/_jsx(InspectorControls, { group: "advanced", children: /*#__PURE__*/_jsx(HTMLElementControl, { tagName: tagName, onChange: onSelectTagName, clientId: clientId, options: [{ label: __('Default (<div>)'), value: 'div' }, { label: '<main>', value: 'main' }, { label: '<section>', value: 'section' }, { label: '<article>', value: 'article' }] }) }); } export default function PostContentEdit({ context, attributes: { tagName = 'div' }, setAttributes, clientId, __unstableLayoutClassNames: layoutClassNames, __unstableParentLayout: parentLayout }) { const { postId: contextPostId, postType: contextPostType } = context; const hasAlreadyRendered = useHasRecursion(contextPostId); if (contextPostId && contextPostType && hasAlreadyRendered) { return /*#__PURE__*/_jsx(RecursionError, {}); } const handleSelectTagName = value => { setAttributes({ tagName: value }); }; return /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(PostContentEditControls, { tagName: tagName, onSelectTagName: handleSelectTagName, clientId: clientId }), /*#__PURE__*/_jsx(RecursionProvider, { uniqueId: contextPostId, children: contextPostId && contextPostType ? /*#__PURE__*/_jsx(Content, { context: context, parentLayout: parentLayout, layoutClassNames: layoutClassNames }) : /*#__PURE__*/_jsx(Placeholder, { layoutClassNames: layoutClassNames }) })] }); } //# sourceMappingURL=edit.js.map