diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index e8480912a87f03..6bb1861abd0a2b 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -7,6 +7,7 @@ export const mayDisplayControlsKey = Symbol( 'mayDisplayControls' ); export const mayDisplayParentControlsKey = Symbol( 'mayDisplayParentControls' ); export const blockEditingModeKey = Symbol( 'blockEditingMode' ); export const blockBindingsKey = Symbol( 'blockBindings' ); +export const isPreviewModeKey = Symbol( 'isPreviewMode' ); export const DEFAULT_BLOCK_EDIT_CONTEXT = { name: '', diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 4e94a8a427510d..57df36c7c74a0b 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -15,6 +15,7 @@ import { mayDisplayParentControlsKey, blockEditingModeKey, blockBindingsKey, + isPreviewModeKey, } from './context'; /** @@ -31,6 +32,7 @@ export default function BlockEdit( { mayDisplayControls, mayDisplayParentControls, blockEditingMode, + isPreviewMode, // The remaining props are passed through the BlockEdit filters and are thus // public API! ...props @@ -65,6 +67,7 @@ export default function BlockEdit( { [ mayDisplayParentControlsKey ]: mayDisplayParentControls, [ blockEditingModeKey ]: blockEditingMode, [ blockBindingsKey ]: bindings, + [ isPreviewModeKey ]: isPreviewMode, } ), [ name, @@ -77,6 +80,7 @@ export default function BlockEdit( { mayDisplayParentControls, blockEditingMode, bindings, + isPreviewMode, ] ) } > diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 8d402f162d52d8..9cedcc1b6cc11d 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -143,6 +143,7 @@ function BlockListBlock( { mayDisplayControls={ mayDisplayControls } mayDisplayParentControls={ mayDisplayParentControls } blockEditingMode={ context.blockEditingMode } + isPreviewMode={ context.isPreviewMode } /> ); @@ -572,6 +573,7 @@ function BlockListBlockProvider( props ) { } = getSettings(); const hasLightBlockWrapper = blockType?.apiVersion > 1; const previewContext = { + isPreviewMode, blockWithoutAttributes, name: blockName, attributes, @@ -671,6 +673,7 @@ function BlockListBlockProvider( props ) { ); const { + isPreviewMode, // Fill values that end up as a public API and may not be defined in // preview mode. mode = 'visual', @@ -728,6 +731,7 @@ function BlockListBlockProvider( props ) { } const privateContext = { + isPreviewMode, clientId, className, index, diff --git a/packages/block-editor/src/components/rich-text/content.js b/packages/block-editor/src/components/rich-text/content.js index 92e150fb174edb..64f747879c4e9e 100644 --- a/packages/block-editor/src/components/rich-text/content.js +++ b/packages/block-editor/src/components/rich-text/content.js @@ -15,33 +15,40 @@ import RichText from './'; */ import { getMultilineTag } from './utils'; -export function Content( { - value, - tagName: Tag, - multiline, - format, - ...props -} ) { +export function valueToHTMLString( value, multiline ) { if ( RichText.isEmpty( value ) ) { - const MultilineTag = getMultilineTag( multiline ); - value = MultilineTag ? : null; - } else if ( Array.isArray( value ) ) { + const multilineTag = getMultilineTag( multiline ); + return multilineTag ? `<${ multilineTag }>` : ''; + } + + if ( Array.isArray( value ) ) { deprecated( 'wp.blockEditor.RichText value prop as children type', { since: '6.1', version: '6.3', alternative: 'value prop as string', link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/', } ); - value = { childrenSource.toHTML( value ) }; - } else if ( typeof value === 'string' ) { - // To do: deprecate. - value = { value }; - } else { - // To do: create a toReactComponent method on RichTextData, which we - // might in the future also use for the editable tree. See - // https://github.com/WordPress/gutenberg/pull/41655. - value = { value.toHTMLString() }; + return childrenSource.toHTML( value ); + } + + // To do: deprecate string type. + if ( typeof value === 'string' ) { + return value; } + // To do: create a toReactComponent method on RichTextData, which we + // might in the future also use for the editable tree. See + // https://github.com/WordPress/gutenberg/pull/41655. + return value.toHTMLString(); +} + +export function Content( { + value, + tagName: Tag, + multiline, + format, + ...props +} ) { + value = { valueToHTMLString( value, multiline ) }; return Tag ? { value } : value; } diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 879bcb3bdba550..fac1a594b1c954 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -26,7 +26,7 @@ import { getBlockType, store as blocksStore } from '@wordpress/blocks'; */ import { useBlockEditorAutocompleteProps } from '../autocomplete'; import { useBlockEditContext } from '../block-edit'; -import { blockBindingsKey } from '../block-edit/context'; +import { blockBindingsKey, isPreviewModeKey } from '../block-edit/context'; import FormatToolbarContainer from './format-toolbar-container'; import { store as blockEditorStore } from '../../store'; import { useUndoAutomaticChange } from './use-undo-automatic-change'; @@ -44,7 +44,7 @@ import { useInsertReplacementText } from './use-insert-replacement-text'; import { useFirefoxCompat } from './use-firefox-compat'; import FormatEdit from './format-edit'; import { getAllowedFormats } from './utils'; -import { Content } from './content'; +import { Content, valueToHTMLString } from './content'; import { withDeprecations } from './with-deprecations'; import { unlock } from '../../lock-unlock'; import { canBindBlock } from '../../hooks/use-bindings-attributes'; @@ -485,6 +485,50 @@ PrivateRichText.isEmpty = ( value ) => { * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/rich-text/README.md */ const PublicForwardedRichTextContainer = forwardRef( ( props, ref ) => { + const context = useBlockEditContext(); + const isPreviewMode = context[ isPreviewModeKey ]; + + if ( isPreviewMode ) { + // Remove all non-content props. + const { + children, + tagName: Tag = 'div', + value, + onChange, + isSelected, + multiline, + inlineToolbar, + wrapperClassName, + autocompleters, + onReplace, + placeholder, + allowedFormats, + withoutInteractiveFormatting, + onRemove, + onMerge, + onSplit, + __unstableOnSplitAtEnd, + __unstableOnSplitAtDoubleLineEnd, + identifier, + preserveWhiteSpace, + __unstablePastePlainText, + __unstableEmbedURLOnPaste, + __unstableDisableFormats, + disableLineBreaks, + __unstableAllowPrefixTransformations, + readOnly, + ...contentProps + } = removeNativeProps( props ); + return ( + + ); + } + return ; } );