@wordpress/block-library
Version:
Block library for the WordPress editor.
149 lines (142 loc) • 5 kB
JavaScript
/**
* External dependencies
*/
import { v4 as createId } from 'uuid';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { formatListNumbered as icon } from '@wordpress/icons';
import { insertObject } from '@wordpress/rich-text';
import { RichTextToolbarButton, store as blockEditorStore, privateApis } from '@wordpress/block-editor';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
import { createBlock, store as blocksStore } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import { unlock } from '../lock-unlock';
import { jsx as _jsx } from "react/jsx-runtime";
const {
usesContextKey
} = unlock(privateApis);
export const formatName = 'core/footnote';
const POST_CONTENT_BLOCK_NAME = 'core/post-content';
const SYNCED_PATTERN_BLOCK_NAME = 'core/block';
export const format = {
title: __('Footnote'),
tagName: 'sup',
className: 'fn',
attributes: {
'data-fn': 'data-fn'
},
interactive: true,
contentEditable: false,
[usesContextKey]: ['postType', 'postId'],
edit: function Edit({
value,
onChange,
isObjectActive,
context: {
postType,
postId
}
}) {
const registry = useRegistry();
const {
getSelectedBlockClientId,
getBlocks,
getBlockRootClientId,
getBlockName,
getBlockParentsByBlockName
} = registry.select(blockEditorStore);
const isFootnotesSupported = useSelect(select => {
if (!select(blocksStore).getBlockType('core/footnotes')) {
return false;
}
const allowedBlocks = select(blockEditorStore).getSettings().allowedBlockTypes;
if (allowedBlocks === false || Array.isArray(allowedBlocks) && !allowedBlocks.includes('core/footnotes')) {
return false;
}
const entityRecord = select(coreDataStore).getEntityRecord('postType', postType, postId);
if ('string' !== typeof entityRecord?.meta?.footnotes) {
return false;
}
// Checks if the selected block lives within a pattern.
const {
getBlockParentsByBlockName: _getBlockParentsByBlockName,
getSelectedBlockClientId: _getSelectedBlockClientId
} = select(blockEditorStore);
const parentCoreBlocks = _getBlockParentsByBlockName(_getSelectedBlockClientId(), SYNCED_PATTERN_BLOCK_NAME);
return !parentCoreBlocks || parentCoreBlocks.length === 0;
}, [postType, postId]);
const {
selectionChange,
insertBlock
} = useDispatch(blockEditorStore);
if (!isFootnotesSupported) {
return null;
}
function onClick() {
registry.batch(() => {
let id;
if (isObjectActive) {
const object = value.replacements[value.start];
id = object?.attributes?.['data-fn'];
} else {
id = createId();
const newValue = insertObject(value, {
type: formatName,
attributes: {
'data-fn': id
},
innerHTML: `<a href="#${id}" id="${id}-link">*</a>`
}, value.end, value.end);
newValue.start = newValue.end - 1;
onChange(newValue);
}
const selectedClientId = getSelectedBlockClientId();
/*
* Attempts to find a common parent post content block.
* This allows for locating blocks within a page edited in the site editor.
*/
const parentPostContent = getBlockParentsByBlockName(selectedClientId, POST_CONTENT_BLOCK_NAME);
// When called with a post content block, getBlocks will return
// the block with controlled inner blocks included.
const blocks = parentPostContent.length ? getBlocks(parentPostContent[0]) : getBlocks();
// BFS search to find the first footnote block.
let fnBlock = null;
{
const queue = [...blocks];
while (queue.length) {
const block = queue.shift();
if (block.name === 'core/footnotes') {
fnBlock = block;
break;
}
queue.push(...block.innerBlocks);
}
}
// Maybe this should all also be moved to the entity provider.
// When there is no footnotes block in the post, create one and
// insert it at the bottom.
if (!fnBlock) {
let rootClientId = getBlockRootClientId(selectedClientId);
while (rootClientId && getBlockName(rootClientId) !== POST_CONTENT_BLOCK_NAME) {
rootClientId = getBlockRootClientId(rootClientId);
}
fnBlock = createBlock('core/footnotes');
insertBlock(fnBlock, undefined, rootClientId);
}
selectionChange(fnBlock.clientId, id, 0, 0);
});
}
return /*#__PURE__*/_jsx(RichTextToolbarButton, {
icon: icon,
title: __('Footnote'),
onClick: onClick,
isActive: isObjectActive
});
}
};
//# sourceMappingURL=format.js.map