Skip to content

Commit

Permalink
Footnotes: disable based on post type (#52934)
Browse files Browse the repository at this point in the history
* Footnotes: disable based on post type

* Address feedback

* Fix typo

* Format: disable if block is not registered

* Lock usesContext api

* Use Symbol instead of Math.random
  • Loading branch information
ellatrix authored and ramonjd committed Jul 28, 2023
1 parent 382f4bb commit adc34b3
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 41 deletions.
100 changes: 62 additions & 38 deletions packages/block-editor/src/components/rich-text/format-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,67 @@
* WordPress dependencies
*/
import { getActiveFormat, getActiveObject } from '@wordpress/rich-text';
import { useContext, useMemo } from '@wordpress/element';

export default function FormatEdit( {
formatTypes,
onChange,
onFocus,
value,
forwardedRef,
} ) {
return formatTypes.map( ( settings ) => {
const { name, edit: Edit } = settings;

if ( ! Edit ) {
return null;
}

const activeFormat = getActiveFormat( value, name );
const isActive = activeFormat !== undefined;
const activeObject = getActiveObject( value );
const isObjectActive =
activeObject !== undefined && activeObject.type === name;

return (
<Edit
key={ name }
isActive={ isActive }
activeAttributes={
isActive ? activeFormat.attributes || {} : {}
}
isObjectActive={ isObjectActive }
activeObjectAttributes={
isObjectActive ? activeObject.attributes || {} : {}
}
value={ value }
onChange={ onChange }
onFocus={ onFocus }
contentRef={ forwardedRef }
/>
);
} );
/**
* Internal dependencies
*/
import BlockContext from '../block-context';

const DEFAULT_BLOCK_CONTEXT = {};

export const usesContextKey = Symbol( 'usesContext' );

function Edit( { onChange, onFocus, value, forwardedRef, settings } ) {
const {
name,
edit: EditFunction,
[ usesContextKey ]: usesContext,
} = settings;

const blockContext = useContext( BlockContext );

// Assign context values using the block type's declared context needs.
const context = useMemo( () => {
return usesContext
? Object.fromEntries(
Object.entries( blockContext ).filter( ( [ key ] ) =>
usesContext.includes( key )
)
)
: DEFAULT_BLOCK_CONTEXT;
}, [ usesContext, blockContext ] );

if ( ! EditFunction ) {
return null;
}

const activeFormat = getActiveFormat( value, name );
const isActive = activeFormat !== undefined;
const activeObject = getActiveObject( value );
const isObjectActive =
activeObject !== undefined && activeObject.type === name;

return (
<EditFunction
key={ name }
isActive={ isActive }
activeAttributes={ isActive ? activeFormat.attributes || {} : {} }
isObjectActive={ isObjectActive }
activeObjectAttributes={
isObjectActive ? activeObject.attributes || {} : {}
}
value={ value }
onChange={ onChange }
onFocus={ onFocus }
contentRef={ forwardedRef }
context={ context }
/>
);
}

export default function FormatEdit( { formatTypes, ...props } ) {
return formatTypes.map( ( settings ) => (
<Edit settings={ settings } { ...props } key={ settings.name } />
) );
}
2 changes: 2 additions & 0 deletions packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
default as ReusableBlocksRenameHint,
useReusableBlocksRenameHint,
} from './components/inserter/reusable-block-rename-hint';
import { usesContextKey } from './components/rich-text/format-edit';

/**
* Private @wordpress/block-editor APIs.
Expand All @@ -47,4 +48,5 @@ lock( privateApis, {
ResolutionTool,
ReusableBlocksRenameHint,
useReusableBlocksRenameHint,
usesContextKey,
} );
12 changes: 12 additions & 0 deletions packages/block-library/src/footnotes/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ export default function FootnotesEdit( { context: { postType, postId } } ) {
const footnotes = meta?.footnotes ? JSON.parse( meta.footnotes ) : [];
const blockProps = useBlockProps();

if ( postType !== 'post' && postType !== 'page' ) {
return (
<div { ...blockProps }>
<Placeholder
icon={ <BlockIcon icon={ icon } /> }
label={ __( 'Footnotes' ) }
// To do: add instructions. We can't add new string in RC.
/>
</div>
);
}

if ( ! footnotes.length ) {
return (
<div { ...blockProps }>
Expand Down
25 changes: 23 additions & 2 deletions packages/block-library/src/footnotes/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ import { insertObject } from '@wordpress/rich-text';
import {
RichTextToolbarButton,
store as blockEditorStore,
privateApis,
} from '@wordpress/block-editor';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { createBlock } from '@wordpress/blocks';
import { createBlock, store as blocksStore } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { name } from './block.json';
import { unlock } from '../lock-unlock';

const { usesContextKey } = unlock( privateApis );

export const formatName = 'core/footnote';
export const format = {
Expand All @@ -30,17 +34,34 @@ export const format = {
'data-fn': 'data-fn',
},
contentEditable: false,
edit: function Edit( { value, onChange, isObjectActive } ) {
[ usesContextKey ]: [ 'postType' ],
edit: function Edit( {
value,
onChange,
isObjectActive,
context: { postType },
} ) {
const registry = useRegistry();
const {
getSelectedBlockClientId,
getBlockRootClientId,
getBlockName,
getBlocks,
} = useSelect( blockEditorStore );
const footnotesBlockType = useSelect( ( select ) =>
select( blocksStore ).getBlockType( name )
);
const { selectionChange, insertBlock } =
useDispatch( blockEditorStore );

if ( ! footnotesBlockType ) {
return null;
}

if ( postType !== 'post' && postType !== 'page' ) {
return null;
}

function onClick() {
registry.batch( () => {
let id;
Expand Down
1 change: 0 additions & 1 deletion packages/block-library/src/footnotes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const settings = {
edit,
};

// Would be good to remove the format and HoR if the block is unregistered.
registerFormatType( formatName, format );

export const init = () => {
Expand Down

0 comments on commit adc34b3

Please sign in to comment.