Skip to content

Commit

Permalink
Support template reusable blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Mar 12, 2019
1 parent 0cf7dcd commit 616544f
Showing 1 changed file with 13 additions and 68 deletions.
81 changes: 13 additions & 68 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
hasChildBlocksWithInserterSupport,
parse,
} from '@wordpress/blocks';
import { SVG, Rect, G, Path } from '@wordpress/components';

/***
* Module constants
Expand All @@ -39,6 +40,7 @@ export const INSERTER_UTILITY_NONE = 0;
const MILLISECONDS_PER_HOUR = 3600 * 1000;
const MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
const MILLISECONDS_PER_WEEK = 7 * 24 * 3600 * 1000;
const templateIcon = <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><Rect x="0" fill="none" width="24" height="24" /><G><Path d="M19 3H5c-1.105 0-2 .895-2 2v14c0 1.105.895 2 2 2h14c1.105 0 2-.895 2-2V5c0-1.105-.895-2-2-2zM6 6h5v5H6V6zm4.5 13C9.12 19 8 17.88 8 16.5S9.12 14 10.5 14s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zm3-6l3-5 3 5h-6z" /></G></SVG>;

/**
* Shared reference to an empty array for cases where it is important to avoid
Expand Down Expand Up @@ -651,29 +653,6 @@ export function getLastMultiSelectedBlockClientId( state ) {
return last( getMultiSelectedBlockClientIds( state ) ) || null;
}

/**
* Checks if possibleAncestorId is an ancestor of possibleDescendentId.
*
* @param {Object} state Editor state.
* @param {string} possibleAncestorId Possible ancestor client ID.
* @param {string} possibleDescendentId Possible descent client ID.
*
* @return {boolean} True if possibleAncestorId is an ancestor
* of possibleDescendentId, and false otherwise.
*/
const isAncestorOf = createSelector(
( state, possibleAncestorId, possibleDescendentId ) => {
let idToCheck = possibleDescendentId;
while ( possibleAncestorId !== idToCheck && idToCheck ) {
idToCheck = getBlockRootClientId( state, idToCheck );
}
return possibleAncestorId === idToCheck;
},
( state ) => [
state.blocks.order,
],
);

/**
* Returns true if a multi-selection exists, and the block corresponding to the
* specified client ID is the first block of the multi-selection set, or false
Expand Down Expand Up @@ -1117,42 +1096,6 @@ const canIncludeBlockTypeInInserter = ( state, blockType, rootClientId ) => {
return canInsertBlockTypeUnmemoized( state, blockType.name, rootClientId );
};

/**
* Returns whether we can show a reusable block in the inserter
*
* @param {Object} state Global State
* @param {Object} reusableBlock Reusable block object
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given block type is allowed to be shown in the inserter.
*/
const canIncludeReusableBlockInInserter = ( state, reusableBlock, rootClientId ) => {
if ( ! canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId ) ) {
return false;
}

const referencedBlocks = __experimentalGetParsedReusableBlock( state, reusableBlock.id );
const referencedBlockName = referencedBlocks ? referencedBlocks[ 0 ].name : null;
if ( ! referencedBlockName ) {
return false;
}

const referencedBlockType = getBlockType( referencedBlockName );
if ( ! referencedBlockType ) {
return false;
}

if ( ! canInsertBlockTypeUnmemoized( state, referencedBlockName, rootClientId ) ) {
return false;
}

if ( isAncestorOf( state, reusableBlock.clientId, rootClientId ) ) {
return false;
}

return true;
};

/**
* Determines the items that appear in the inserter. Includes both static
* items (e.g. a regular block type) and dynamic items (e.g. a reusable block).
Expand Down Expand Up @@ -1255,8 +1198,10 @@ export const getInserterItems = createSelector(
const id = `core/block/${ reusableBlock.id }`;

const referencedBlocks = __experimentalGetParsedReusableBlock( state, reusableBlock.id );
const referencedBlockName = referencedBlocks[ 0 ].name;
const referencedBlockType = getBlockType( referencedBlockName );
let referencedBlockType;
if ( referencedBlocks.length === 1 ) {
referencedBlockType = getBlockType( referencedBlocks[ 0 ].name );
}

const { time, count = 0 } = getInsertUsage( state, id ) || {};
const utility = calculateUtility( 'reusable', count, false );
Expand All @@ -1267,7 +1212,7 @@ export const getInserterItems = createSelector(
name: 'core/block',
initialAttributes: { ref: reusableBlock.id },
title: reusableBlock.title,
icon: referencedBlockType.icon,
icon: referencedBlockType ? referencedBlockType.icon : templateIcon,
category: 'reusable',
keywords: [],
isDisabled: false,
Expand All @@ -1280,9 +1225,9 @@ export const getInserterItems = createSelector(
.filter( ( blockType ) => canIncludeBlockTypeInInserter( state, blockType, rootClientId ) )
.map( buildBlockTypeInserterItem );

const reusableBlockInserterItems = getReusableBlocks( state )
.filter( ( block ) => canIncludeReusableBlockInInserter( state, block, rootClientId ) )
.map( buildReusableBlockInserterItem );
const reusableBlockInserterItems = canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId ) ?
getReusableBlocks( state ).map( buildReusableBlockInserterItem ) :
[];

return orderBy(
[ ...blockTypeInserterItems, ...reusableBlockInserterItems ],
Expand Down Expand Up @@ -1318,9 +1263,9 @@ export const hasInserterItems = createSelector(
if ( hasBlockType ) {
return true;
}
const hasReusableBlock = some(
getReusableBlocks( state ),
( block ) => canIncludeReusableBlockInInserter( state, block, rootClientId )
const hasReusableBlock = (
canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId ) &&
getReusableBlocks( state ).length > 0
);

return hasReusableBlock;
Expand Down

0 comments on commit 616544f

Please sign in to comment.