Skip to content

Commit

Permalink
Inserter: Update how we compute the actual insertion point for blocks (
Browse files Browse the repository at this point in the history
…WordPress#65490)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: jorgefilipecosta <[email protected]>
Co-authored-by: jasmussen <[email protected]>
  • Loading branch information
5 people authored Sep 24, 2024
1 parent 8a658c8 commit cf78cf0
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export function BlockTypesTab(
continue;
}

if ( rootClientId && item.rootClientId === rootClientId ) {
if ( rootClientId && item.isAllowedInCurrentRoot ) {
itemsForCurrentRoot.push( item );
} else {
itemsRemaining.push( item );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
* WordPress dependencies
*/
import {
getBlockType,
createBlock,
createBlocksFromInnerBlocksTemplate,
store as blocksStore,
parse,
} from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';
import { useCallback, useMemo } from '@wordpress/element';
import { store as noticesStore } from '@wordpress/notices';
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../../store';
import { withRootClientIdOptionKey } from '../../../store/utils';
import { isFiltered } from '../../../store/utils';
import { unlock } from '../../../lock-unlock';

/**
* Retrieves the block types inserter state.
Expand All @@ -26,7 +30,7 @@ import { withRootClientIdOptionKey } from '../../../store/utils';
*/
const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => {
const options = useMemo(
() => ( { [ withRootClientIdOptionKey ]: ! isQuick } ),
() => ( { [ isFiltered ]: !! isQuick } ),
[ isQuick ]
);
const [ items ] = useSelect(
Expand All @@ -38,6 +42,10 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => {
],
[ rootClientId, options ]
);
const { getClosestAllowedInsertionPoint } = unlock(
useSelect( blockEditorStore )
);
const { createErrorNotice } = useDispatch( noticesStore );

const [ categories, collections ] = useSelect( ( select ) => {
const { getCategories, getCollections } = select( blocksStore );
Expand All @@ -46,16 +54,29 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => {

const onSelectItem = useCallback(
(
{
name,
initialAttributes,
innerBlocks,
syncStatus,
content,
rootClientId: _rootClientId,
},
{ name, initialAttributes, innerBlocks, syncStatus, content },
shouldFocusBlock
) => {
const destinationClientId = getClosestAllowedInsertionPoint(
name,
rootClientId
);
if ( destinationClientId === null ) {
const title = getBlockType( name )?.title ?? name;
createErrorNotice(
sprintf(
/* translators: %s: block pattern title. */
__( 'Block "%s" can\'t be inserted.' ),
title
),
{
type: 'snackbar',
id: 'inserter-notice',
}
);
return;
}

const insertedBlock =
syncStatus === 'unsynced'
? parse( content, {
Expand All @@ -66,15 +87,14 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => {
initialAttributes,
createBlocksFromInnerBlocksTemplate( innerBlocks )
);

onInsert(
insertedBlock,
undefined,
shouldFocusBlock,
_rootClientId
destinationClientId
);
},
[ onInsert ]
[ onInsert, getClosestAllowedInsertionPoint, rootClientId ]
);

return [ items, categories, collections, onSelectItem ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ function useInsertionPoint( {
selectBlockOnInsert = true,
} ) {
const registry = useRegistry();
const { getSelectedBlock } = useSelect( blockEditorStore );
const {
getSelectedBlock,
getClosestAllowedInsertionPoint,
isBlockInsertionPointVisible,
} = unlock( useSelect( blockEditorStore ) );
const { destinationRootClientId, destinationIndex } = useSelect(
( select ) => {
const {
Expand Down Expand Up @@ -193,21 +197,30 @@ function useInsertionPoint( {

const onToggleInsertionPoint = useCallback(
( item ) => {
if ( item?.hasOwnProperty( 'rootClientId' ) ) {
showInsertionPoint(
item.rootClientId,
getIndex( {
destinationRootClientId,
destinationIndex,
rootClientId: item.rootClientId,
registry,
} )
);
if ( item && ! isBlockInsertionPointVisible() ) {
const allowedDestinationRootClientId =
getClosestAllowedInsertionPoint(
item.name,
destinationRootClientId
);
if ( allowedDestinationRootClientId !== null ) {
showInsertionPoint(
allowedDestinationRootClientId,
getIndex( {
destinationRootClientId,
destinationIndex,
rootClientId: allowedDestinationRootClientId,
registry,
} )
);
}
} else {
hideInsertionPoint();
}
},
[
getClosestAllowedInsertionPoint,
isBlockInsertionPointVisible,
showInsertionPoint,
hideInsertionPoint,
destinationRootClientId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const usePatternsState = ( onInsert, rootClientId, selectedCategory ) => {
),
{
type: 'snackbar',
id: 'block-pattern-inserted-notice',
id: 'inserter-notice',
}
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,16 @@ export function MediaPreview( { media, onClick, category } ) {
} );
createSuccessNotice(
__( 'Image uploaded and inserted.' ),
{ type: 'snackbar' }
{ type: 'snackbar', id: 'inserter-notice' }
);
setIsInserting( false );
},
allowedTypes: ALLOWED_MEDIA_TYPES,
onError( message ) {
createErrorNotice( message, { type: 'snackbar' } );
createErrorNotice( message, {
type: 'snackbar',
id: 'inserter-notice',
} );
setIsInserting( false );
},
} );
Expand Down Expand Up @@ -281,6 +284,7 @@ export function MediaPreview( { media, onClick, category } ) {
onClick( cloneBlock( block ) );
createSuccessNotice( __( 'Image inserted.' ), {
type: 'snackbar',
id: 'inserter-notice',
} );
setShowExternalUploadModal( false );
} }
Expand Down

This file was deleted.

38 changes: 38 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
getTemplateLock,
getClientIdsWithDescendants,
isNavigationMode,
getBlockRootClientId,
} from './selectors';
import {
checkAllowListRecursive,
Expand Down Expand Up @@ -637,3 +638,40 @@ export function getZoomLevel( state ) {
export function isZoomOut( state ) {
return getZoomLevel( state ) < 100;
}

/**
* Finds the closest block where the block is allowed to be inserted.
*
* @param {Object} state Editor state.
* @param {string} name Block name.
* @param {string} clientId Default insertion point.
*
* @return {string} clientID of the closest container when the block name can be inserted.
*/
export function getClosestAllowedInsertionPoint( state, name, clientId = '' ) {
// If we're trying to insert at the root level and it's not allowed
// Try the section root instead.
if ( ! clientId ) {
if ( canInsertBlockType( state, name, clientId ) ) {
return clientId;
}

const sectionRootClientId = getSectionRootClientId( state );
if (
sectionRootClientId &&
canInsertBlockType( state, name, sectionRootClientId )
) {
return sectionRootClientId;
}
return null;
}

// Traverse the block tree up until we find a place where we can insert.
let current = clientId;
while ( current !== null && ! canInsertBlockType( state, name, current ) ) {
const parentClientId = getBlockRootClientId( state, current );
current = parentClientId;
}

return current;
}
Loading

0 comments on commit cf78cf0

Please sign in to comment.