UNPKG

@wordpress/block-editor

Version:
8 lines (7 loc) 11.3 kB
{ "version": 3, "sources": ["../../src/hooks/block-hooks.js"], "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { Fragment, useMemo } from '@wordpress/element';\nimport { PanelBody, ToggleControl } from '@wordpress/components';\nimport { createBlock, store as blocksStore } from '@wordpress/blocks';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { InspectorControls } from '../components';\nimport { store as blockEditorStore } from '../store';\n\nconst EMPTY_OBJECT = {};\n\nfunction BlockHooksControlPure( {\n\tname,\n\tclientId,\n\tmetadata: { ignoredHookedBlocks = [] } = {},\n} ) {\n\tconst blockTypes = useSelect(\n\t\t( select ) => select( blocksStore ).getBlockTypes(),\n\t\t[]\n\t);\n\n\t// A hooked block added via a filter will not be exposed through a block\n\t// type's `blockHooks` property; however, if the containing layout has been\n\t// modified, it will be present in the anchor block's `ignoredHookedBlocks`\n\t// metadata.\n\tconst hookedBlocksForCurrentBlock = useMemo(\n\t\t() =>\n\t\t\tblockTypes?.filter(\n\t\t\t\t( { name: blockName, blockHooks } ) =>\n\t\t\t\t\t( blockHooks && name in blockHooks ) ||\n\t\t\t\t\tignoredHookedBlocks.includes( blockName )\n\t\t\t),\n\t\t[ blockTypes, name, ignoredHookedBlocks ]\n\t);\n\n\tconst hookedBlockClientIds = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getBlocks, getBlockRootClientId, getGlobalBlockCount } =\n\t\t\t\tselect( blockEditorStore );\n\n\t\t\tconst rootClientId = getBlockRootClientId( clientId );\n\t\t\tconst _hookedBlockClientIds = hookedBlocksForCurrentBlock.reduce(\n\t\t\t\t( clientIds, block ) => {\n\t\t\t\t\t// If the block doesn't exist anywhere in the block tree,\n\t\t\t\t\t// we know that we have to set the toggle to disabled.\n\t\t\t\t\tif ( getGlobalBlockCount( block.name ) === 0 ) {\n\t\t\t\t\t\treturn clientIds;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst relativePosition = block?.blockHooks?.[ name ];\n\t\t\t\t\tlet candidates;\n\n\t\t\t\t\tswitch ( relativePosition ) {\n\t\t\t\t\t\tcase 'before':\n\t\t\t\t\t\tcase 'after':\n\t\t\t\t\t\t\t// Any of the current block's siblings (with the right block type) qualifies\n\t\t\t\t\t\t\t// as a hooked block (inserted `before` or `after` the current one), as the block\n\t\t\t\t\t\t\t// might've been automatically inserted and then moved around a bit by the user.\n\t\t\t\t\t\t\tcandidates = getBlocks( rootClientId );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'first_child':\n\t\t\t\t\t\tcase 'last_child':\n\t\t\t\t\t\t\t// Any of the current block's child blocks (with the right block type) qualifies\n\t\t\t\t\t\t\t// as a hooked first or last child block, as the block might've been automatically\n\t\t\t\t\t\t\t// inserted and then moved around a bit by the user.\n\t\t\t\t\t\t\tcandidates = getBlocks( clientId );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase undefined:\n\t\t\t\t\t\t\t// If we haven't found a blockHooks field with a relative position for the hooked\n\t\t\t\t\t\t\t// block, it means that it was added by a filter. In this case, we look for the block\n\t\t\t\t\t\t\t// both among the current block's siblings and its children.\n\t\t\t\t\t\t\tcandidates = [\n\t\t\t\t\t\t\t\t...getBlocks( rootClientId ),\n\t\t\t\t\t\t\t\t...getBlocks( clientId ),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst hookedBlock = candidates?.find(\n\t\t\t\t\t\t( candidate ) => candidate.name === block.name\n\t\t\t\t\t);\n\n\t\t\t\t\t// If the block exists in the designated location, we consider it hooked\n\t\t\t\t\t// and show the toggle as enabled.\n\t\t\t\t\tif ( hookedBlock ) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...clientIds,\n\t\t\t\t\t\t\t[ block.name ]: hookedBlock.clientId,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// If no hooked block was found in any of its designated locations,\n\t\t\t\t\t// we set the toggle to disabled.\n\t\t\t\t\treturn clientIds;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t);\n\n\t\t\tif ( Object.values( _hookedBlockClientIds ).length > 0 ) {\n\t\t\t\treturn _hookedBlockClientIds;\n\t\t\t}\n\n\t\t\treturn EMPTY_OBJECT;\n\t\t},\n\t\t[ hookedBlocksForCurrentBlock, name, clientId ]\n\t);\n\n\tconst { getBlockIndex, getBlockCount, getBlockRootClientId } =\n\t\tuseSelect( blockEditorStore );\n\tconst { insertBlock, removeBlock } = useDispatch( blockEditorStore );\n\n\tif ( ! hookedBlocksForCurrentBlock.length ) {\n\t\treturn null;\n\t}\n\n\t// Group by block namespace (i.e. prefix before the slash).\n\tconst groupedHookedBlocks = hookedBlocksForCurrentBlock.reduce(\n\t\t( groups, block ) => {\n\t\t\tconst [ namespace ] = block.name.split( '/' );\n\t\t\tif ( ! groups[ namespace ] ) {\n\t\t\t\tgroups[ namespace ] = [];\n\t\t\t}\n\t\t\tgroups[ namespace ].push( block );\n\t\t\treturn groups;\n\t\t},\n\t\t{}\n\t);\n\n\tconst insertBlockIntoDesignatedLocation = ( block, relativePosition ) => {\n\t\tconst blockIndex = getBlockIndex( clientId );\n\t\tconst innerBlocksLength = getBlockCount( clientId );\n\t\tconst rootClientId = getBlockRootClientId( clientId );\n\n\t\tswitch ( relativePosition ) {\n\t\t\tcase 'before':\n\t\t\tcase 'after':\n\t\t\t\tinsertBlock(\n\t\t\t\t\tblock,\n\t\t\t\t\trelativePosition === 'after' ? blockIndex + 1 : blockIndex,\n\t\t\t\t\trootClientId, // Insert as a child of the current block's parent\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'first_child':\n\t\t\tcase 'last_child':\n\t\t\t\tinsertBlock(\n\t\t\t\t\tblock,\n\t\t\t\t\t// TODO: It'd be great if insertBlock() would accept negative indices for insertion.\n\t\t\t\t\trelativePosition === 'first_child' ? 0 : innerBlocksLength,\n\t\t\t\t\tclientId, // Insert as a child of the current block.\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase undefined:\n\t\t\t\t// If we do not know the relative position, it is because the block was\n\t\t\t\t// added via a filter. In this case, we default to inserting it after the\n\t\t\t\t// current block.\n\t\t\t\tinsertBlock(\n\t\t\t\t\tblock,\n\t\t\t\t\tblockIndex + 1,\n\t\t\t\t\trootClientId, // Insert as a child of the current block's parent\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\treturn (\n\t\t<InspectorControls>\n\t\t\t<PanelBody\n\t\t\t\tclassName=\"block-editor-hooks__block-hooks\"\n\t\t\t\ttitle={ __( 'Plugins' ) }\n\t\t\t\tinitialOpen\n\t\t\t>\n\t\t\t\t<p className=\"block-editor-hooks__block-hooks-helptext\">\n\t\t\t\t\t{ __(\n\t\t\t\t\t\t'Manage the inclusion of blocks added automatically by plugins.'\n\t\t\t\t\t) }\n\t\t\t\t</p>\n\t\t\t\t{ Object.keys( groupedHookedBlocks ).map( ( vendor ) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Fragment key={ vendor }>\n\t\t\t\t\t\t\t<h3>{ vendor }</h3>\n\t\t\t\t\t\t\t{ groupedHookedBlocks[ vendor ].map( ( block ) => {\n\t\t\t\t\t\t\t\tconst checked =\n\t\t\t\t\t\t\t\t\tblock.name in hookedBlockClientIds;\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\t\t\t\tchecked={ checked }\n\t\t\t\t\t\t\t\t\t\tkey={ block.title }\n\t\t\t\t\t\t\t\t\t\tlabel={ block.title }\n\t\t\t\t\t\t\t\t\t\tonChange={ () => {\n\t\t\t\t\t\t\t\t\t\t\tif ( ! checked ) {\n\t\t\t\t\t\t\t\t\t\t\t\t// Create and insert block.\n\t\t\t\t\t\t\t\t\t\t\t\tconst relativePosition =\n\t\t\t\t\t\t\t\t\t\t\t\t\tblock.blockHooks[ name ];\n\t\t\t\t\t\t\t\t\t\t\t\tinsertBlockIntoDesignatedLocation(\n\t\t\t\t\t\t\t\t\t\t\t\t\tcreateBlock( block.name ),\n\t\t\t\t\t\t\t\t\t\t\t\t\trelativePosition\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Remove block.\n\t\t\t\t\t\t\t\t\t\t\tremoveBlock(\n\t\t\t\t\t\t\t\t\t\t\t\thookedBlockClientIds[\n\t\t\t\t\t\t\t\t\t\t\t\t\tblock.name\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} ) }\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t);\n\t\t\t\t} ) }\n\t\t\t</PanelBody>\n\t\t</InspectorControls>\n\t);\n}\n\nexport default {\n\tedit: BlockHooksControlPure,\n\tattributeKeys: [ 'metadata' ],\n\thasSupport() {\n\t\treturn true;\n\t},\n};\n"], "mappings": "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", "names": ["import_components", "blocksStore", "getBlockRootClientId", "blockEditorStore"] }