UNPKG

@wordpress/block-library

Version:
137 lines (130 loc) 4.32 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useMerge; var _data = require("@wordpress/data"); var _blockEditor = require("@wordpress/block-editor"); var _useOutdentListItem = _interopRequireDefault(require("./use-outdent-list-item")); /** * WordPress dependencies */ /** * Internal dependencies */ function useMerge(clientId, onMerge) { const registry = (0, _data.useRegistry)(); const { getPreviousBlockClientId, getNextBlockClientId, getBlockOrder, getBlockRootClientId, getBlockName } = (0, _data.useSelect)(_blockEditor.store); const { mergeBlocks, moveBlocksToPosition } = (0, _data.useDispatch)(_blockEditor.store); const outdentListItem = (0, _useOutdentListItem.default)(); function getTrailingId(id) { const order = getBlockOrder(id); if (!order.length) { return id; } return getTrailingId(order[order.length - 1]); } function getParentListItemId(id) { const listId = getBlockRootClientId(id); const parentListItemId = getBlockRootClientId(listId); if (!parentListItemId) { return; } if (getBlockName(parentListItemId) !== 'core/list-item') { return; } return parentListItemId; } /** * Return the next list item with respect to the given list item. If none, * return the next list item of the parent list item if it exists. * * @param {string} id A list item client ID. * @return {?string} The client ID of the next list item. */ function _getNextId(id) { const next = getNextBlockClientId(id); if (next) { return next; } const parentListItemId = getParentListItemId(id); if (!parentListItemId) { return; } return _getNextId(parentListItemId); } /** * Given a client ID, return the client ID of the list item on the next * line, regardless of indentation level. * * @param {string} id The client ID of the current list item. * @return {?string} The client ID of the next list item. */ function getNextId(id) { const order = getBlockOrder(id); // If the list item does not have a nested list, return the next list // item. if (!order.length) { return _getNextId(id); } // Get the first list item in the nested list. return getBlockOrder(order[0])[0]; } return forward => { function mergeWithNested(clientIdA, clientIdB) { registry.batch(() => { // When merging a sub list item with a higher next list item, we // also need to move any nested list items. Check if there's a // listed list, and append its nested list items to the current // list. const [nestedListClientId] = getBlockOrder(clientIdB); if (nestedListClientId) { // If we are merging with the previous list item, and the // previous list item does not have nested list, move the // nested list to the previous list item. if (getPreviousBlockClientId(clientIdB) === clientIdA && !getBlockOrder(clientIdA).length) { moveBlocksToPosition([nestedListClientId], clientIdB, clientIdA); } else { moveBlocksToPosition(getBlockOrder(nestedListClientId), nestedListClientId, getBlockRootClientId(clientIdA)); } } mergeBlocks(clientIdA, clientIdB); }); } if (forward) { const nextBlockClientId = getNextId(clientId); if (!nextBlockClientId) { onMerge(forward); return; } if (getParentListItemId(nextBlockClientId)) { outdentListItem(nextBlockClientId); } else { mergeWithNested(clientId, nextBlockClientId); } } else { // Merging is only done from the top level. For lowel levels, the // list item is outdented instead. const previousBlockClientId = getPreviousBlockClientId(clientId); if (getParentListItemId(clientId)) { outdentListItem(clientId); } else if (previousBlockClientId) { const trailingId = getTrailingId(previousBlockClientId); mergeWithNested(trailingId, clientId); } else { onMerge(forward); } } }; } //# sourceMappingURL=use-merge.js.map