UNPKG

@wordpress/block-editor

Version:
1,189 lines (1,188 loc) 35.8 kB
// packages/block-editor/src/store/actions.js import { cloneBlock, __experimentalCloneSanitizedBlock, createBlock, doBlocksMatchTemplate, getBlockType, getDefaultBlockName, hasBlockSupport, switchToBlockType, synchronizeBlocksWithTemplate, getBlockSupport, isUnmodifiedDefaultBlock, isUnmodifiedBlock } from "@wordpress/blocks"; import { speak } from "@wordpress/a11y"; import { __, _n, sprintf } from "@wordpress/i18n"; import { store as noticesStore } from "@wordpress/notices"; import { create, insert, remove, toHTMLString } from "@wordpress/rich-text"; import deprecated from "@wordpress/deprecated"; import { store as preferencesStore } from "@wordpress/preferences"; import { retrieveSelectedAttribute, findRichTextAttributeKey, START_OF_SELECTED_AREA } from "../utils/selection"; import { __experimentalUpdateSettings, privateRemoveBlocks, editContentOnlySection } from "./private-actions"; var castArray = (maybeArray) => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; var resetBlocks = (blocks) => ({ dispatch }) => { dispatch({ type: "RESET_BLOCKS", blocks }); dispatch(validateBlocksToTemplate(blocks)); }; var validateBlocksToTemplate = (blocks) => ({ select, dispatch }) => { const template = select.getTemplate(); const templateLock = select.getTemplateLock(); const isBlocksValidToTemplate = !template || templateLock !== "all" || doBlocksMatchTemplate(blocks, template); const isValidTemplate = select.isValidTemplate(); if (isBlocksValidToTemplate !== isValidTemplate) { dispatch.setTemplateValidity(isBlocksValidToTemplate); return isBlocksValidToTemplate; } }; function resetSelection(selectionStart, selectionEnd, initialPosition) { return { type: "RESET_SELECTION", selectionStart, selectionEnd, initialPosition }; } function receiveBlocks(blocks) { deprecated('wp.data.dispatch( "core/block-editor" ).receiveBlocks', { since: "5.9", alternative: "resetBlocks or insertBlocks" }); return { type: "RECEIVE_BLOCKS", blocks }; } function updateBlockAttributes(clientIds, attributes, options = { uniqueByBlock: false }) { if (typeof options === "boolean") { options = { uniqueByBlock: options }; } return { type: "UPDATE_BLOCK_ATTRIBUTES", clientIds: castArray(clientIds), attributes, options }; } function updateBlock(clientId, updates) { return { type: "UPDATE_BLOCK", clientId, updates }; } function selectBlock(clientId, initialPosition = 0) { return { type: "SELECT_BLOCK", initialPosition, clientId }; } function hoverBlock() { deprecated('wp.data.dispatch( "core/block-editor" ).hoverBlock', { since: "6.9", version: "7.1" }); return { type: "DO_NOTHING" }; } var selectPreviousBlock = (clientId, fallbackToParent = false) => ({ select, dispatch }) => { const previousBlockClientId = select.getPreviousBlockClientId(clientId); if (previousBlockClientId) { dispatch.selectBlock(previousBlockClientId, -1); } else if (fallbackToParent) { const firstParentClientId = select.getBlockRootClientId(clientId); if (firstParentClientId) { dispatch.selectBlock(firstParentClientId, -1); } } }; var selectNextBlock = (clientId) => ({ select, dispatch }) => { const nextBlockClientId = select.getNextBlockClientId(clientId); if (nextBlockClientId) { dispatch.selectBlock(nextBlockClientId); } }; function startMultiSelect() { return { type: "START_MULTI_SELECT" }; } function stopMultiSelect() { return { type: "STOP_MULTI_SELECT" }; } var multiSelect = (start, end, __experimentalInitialPosition = 0) => ({ select, dispatch }) => { const startBlockRootClientId = select.getBlockRootClientId(start); const endBlockRootClientId = select.getBlockRootClientId(end); if (startBlockRootClientId !== endBlockRootClientId) { return; } dispatch({ type: "MULTI_SELECT", start, end, initialPosition: __experimentalInitialPosition }); const blockCount = select.getSelectedBlockCount(); speak( sprintf( /* translators: %s: number of selected blocks */ _n("%s block selected.", "%s blocks selected.", blockCount), blockCount ), "assertive" ); }; function clearSelectedBlock() { return { type: "CLEAR_SELECTED_BLOCK" }; } function toggleSelection(isSelectionEnabled = true) { return { type: "TOGGLE_SELECTION", isSelectionEnabled }; } var replaceBlocks = (clientIds, blocks, indexToSelect, initialPosition = 0, meta) => ({ select, dispatch, registry }) => { clientIds = castArray(clientIds); blocks = castArray(blocks); const rootClientId = select.getBlockRootClientId(clientIds[0]); for (let index = 0; index < blocks.length; index++) { const block = blocks[index]; const canInsertBlock = select.canInsertBlockType( block.name, rootClientId ); if (!canInsertBlock) { return; } } registry.batch(() => { dispatch({ type: "REPLACE_BLOCKS", clientIds, blocks, time: Date.now(), indexToSelect, initialPosition, meta }); dispatch.ensureDefaultBlock(); }); }; function replaceBlock(clientId, block) { return replaceBlocks(clientId, block); } var createOnMove = (type) => (clientIds, rootClientId) => ({ select, dispatch }) => { const canMoveBlocks = select.canMoveBlocks(clientIds); if (!canMoveBlocks) { return; } dispatch({ type, clientIds: castArray(clientIds), rootClientId }); }; var moveBlocksDown = createOnMove("MOVE_BLOCKS_DOWN"); var moveBlocksUp = createOnMove("MOVE_BLOCKS_UP"); var moveBlocksToPosition = (clientIds, fromRootClientId = "", toRootClientId = "", index) => ({ select, dispatch }) => { const canMoveBlocks = select.canMoveBlocks(clientIds); if (!canMoveBlocks) { return; } if (fromRootClientId !== toRootClientId) { const canRemoveBlocks = select.canRemoveBlocks(clientIds); if (!canRemoveBlocks) { return; } const canInsertBlocks = select.canInsertBlocks( clientIds, toRootClientId ); if (!canInsertBlocks) { return; } } dispatch({ type: "MOVE_BLOCKS_TO_POSITION", fromRootClientId, toRootClientId, clientIds, index }); }; function moveBlockToPosition(clientId, fromRootClientId = "", toRootClientId = "", index) { return moveBlocksToPosition( [clientId], fromRootClientId, toRootClientId, index ); } function insertBlock(block, index, rootClientId, updateSelection, meta) { return insertBlocks( [block], index, rootClientId, updateSelection, 0, meta ); } var insertBlocks = (blocks, index, rootClientId, updateSelection = true, initialPosition = 0, meta) => ({ select, dispatch }) => { if (initialPosition !== null && typeof initialPosition === "object") { meta = initialPosition; initialPosition = 0; deprecated( "meta argument in wp.data.dispatch('core/block-editor')", { since: "5.8", hint: "The meta argument is now the 6th argument of the function" } ); } blocks = castArray(blocks); const allowedBlocks = []; for (const block of blocks) { const isValid = select.canInsertBlockType( block.name, rootClientId ); if (isValid) { allowedBlocks.push(block); } } if (allowedBlocks.length) { dispatch({ type: "INSERT_BLOCKS", blocks: allowedBlocks, index, rootClientId, time: Date.now(), updateSelection, initialPosition: updateSelection ? initialPosition : null, meta }); } }; function showInsertionPoint(rootClientId, index, __unstableOptions = {}) { const { __unstableWithInserter, operation, nearestSide } = __unstableOptions; return { type: "SHOW_INSERTION_POINT", rootClientId, index, __unstableWithInserter, operation, nearestSide }; } var hideInsertionPoint = () => ({ select, dispatch }) => { if (!select.isBlockInsertionPointVisible()) { return; } dispatch({ type: "HIDE_INSERTION_POINT" }); }; function setTemplateValidity(isValid) { return { type: "SET_TEMPLATE_VALIDITY", isValid }; } var synchronizeTemplate = () => ({ select, dispatch }) => { dispatch({ type: "SYNCHRONIZE_TEMPLATE" }); const blocks = select.getBlocks(); const template = select.getTemplate(); const updatedBlockList = synchronizeBlocksWithTemplate( blocks, template ); dispatch.resetBlocks(updatedBlockList); }; var __unstableDeleteSelection = (isForward) => ({ registry, select, dispatch }) => { const selectionAnchor = select.getSelectionStart(); const selectionFocus = select.getSelectionEnd(); if (selectionAnchor.clientId === selectionFocus.clientId) { return; } if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === "undefined" || typeof selectionFocus.offset === "undefined") { return false; } const anchorRootClientId = select.getBlockRootClientId( selectionAnchor.clientId ); const focusRootClientId = select.getBlockRootClientId( selectionFocus.clientId ); if (anchorRootClientId !== focusRootClientId) { return; } const blockOrder = select.getBlockOrder(anchorRootClientId); const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); const focusIndex = blockOrder.indexOf(selectionFocus.clientId); let selectionStart, selectionEnd; if (anchorIndex > focusIndex) { selectionStart = selectionFocus; selectionEnd = selectionAnchor; } else { selectionStart = selectionAnchor; selectionEnd = selectionFocus; } const targetSelection = isForward ? selectionEnd : selectionStart; const targetBlock = select.getBlock(targetSelection.clientId); const targetBlockType = getBlockType(targetBlock.name); if (!targetBlockType.merge) { return; } const selectionA = selectionStart; const selectionB = selectionEnd; const blockA = select.getBlock(selectionA.clientId); const blockB = select.getBlock(selectionB.clientId); const htmlA = blockA.attributes[selectionA.attributeKey]; const htmlB = blockB.attributes[selectionB.attributeKey]; let valueA = create({ html: htmlA }); let valueB = create({ html: htmlB }); valueA = remove(valueA, selectionA.offset, valueA.text.length); valueB = insert(valueB, START_OF_SELECTED_AREA, 0, selectionB.offset); const cloneA = cloneBlock(blockA, { [selectionA.attributeKey]: toHTMLString({ value: valueA }) }); const cloneB = cloneBlock(blockB, { [selectionB.attributeKey]: toHTMLString({ value: valueB }) }); const followingBlock = isForward ? cloneA : cloneB; const blocksWithTheSameType = blockA.name === blockB.name ? [followingBlock] : switchToBlockType(followingBlock, targetBlockType.name); if (!blocksWithTheSameType || !blocksWithTheSameType.length) { return; } let updatedAttributes; if (isForward) { const blockToMerge = blocksWithTheSameType.pop(); updatedAttributes = targetBlockType.merge( blockToMerge.attributes, cloneB.attributes ); } else { const blockToMerge = blocksWithTheSameType.shift(); updatedAttributes = targetBlockType.merge( cloneA.attributes, blockToMerge.attributes ); } const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); const convertedHtml = updatedAttributes[newAttributeKey]; const convertedValue = create({ html: convertedHtml }); const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA); const newValue = remove(convertedValue, newOffset, newOffset + 1); const newHtml = toHTMLString({ value: newValue }); updatedAttributes[newAttributeKey] = newHtml; const selectedBlockClientIds = select.getSelectedBlockClientIds(); const replacement = [ ...isForward ? blocksWithTheSameType : [], { // Preserve the original client ID. ...targetBlock, attributes: { ...targetBlock.attributes, ...updatedAttributes } }, ...isForward ? [] : blocksWithTheSameType ]; registry.batch(() => { dispatch.selectionChange( targetBlock.clientId, newAttributeKey, newOffset, newOffset ); dispatch.replaceBlocks( selectedBlockClientIds, replacement, 0, // If we don't pass the `indexToSelect` it will default to the last block. select.getSelectedBlocksInitialCaretPosition() ); }); }; var __unstableSplitSelection = (blocks = []) => ({ registry, select, dispatch }) => { const selectionAnchor = select.getSelectionStart(); const selectionFocus = select.getSelectionEnd(); const anchorRootClientId = select.getBlockRootClientId( selectionAnchor.clientId ); const focusRootClientId = select.getBlockRootClientId( selectionFocus.clientId ); if (anchorRootClientId !== focusRootClientId) { return; } const blockOrder = select.getBlockOrder(anchorRootClientId); const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); const focusIndex = blockOrder.indexOf(selectionFocus.clientId); let selectionStart, selectionEnd; if (anchorIndex > focusIndex) { selectionStart = selectionFocus; selectionEnd = selectionAnchor; } else { selectionStart = selectionAnchor; selectionEnd = selectionFocus; } const selectionA = selectionStart; const selectionB = selectionEnd; const blockA = select.getBlock(selectionA.clientId); const blockB = select.getBlock(selectionB.clientId); const blockAType = getBlockType(blockA.name); const blockBType = getBlockType(blockB.name); const attributeKeyA = typeof selectionA.attributeKey === "string" ? selectionA.attributeKey : findRichTextAttributeKey(blockAType); const attributeKeyB = typeof selectionB.attributeKey === "string" ? selectionB.attributeKey : findRichTextAttributeKey(blockBType); const blockAttributes = select.getBlockAttributes( selectionA.clientId ); const bindings = blockAttributes?.metadata?.bindings; if (bindings?.[attributeKeyA]) { if (blocks.length) { const { createWarningNotice } = registry.dispatch(noticesStore); createWarningNotice( __( "Blocks can't be inserted into other blocks with bindings" ), { type: "snackbar" } ); return; } dispatch.insertAfterBlock(selectionA.clientId); return; } if (!attributeKeyA || !attributeKeyB || typeof selectionAnchor.offset === "undefined" || typeof selectionFocus.offset === "undefined") { return; } if (selectionA.clientId === selectionB.clientId && attributeKeyA === attributeKeyB && selectionA.offset === selectionB.offset) { if (blocks.length) { if (isUnmodifiedDefaultBlock(blockA)) { dispatch.replaceBlocks( [selectionA.clientId], blocks, blocks.length - 1, -1 ); return; } } else if (!select.getBlockOrder(selectionA.clientId).length) { let createEmpty2 = function() { const defaultBlockName2 = getDefaultBlockName(); return select.canInsertBlockType( defaultBlockName2, anchorRootClientId ) ? createBlock(defaultBlockName2) : createBlock( select.getBlockName(selectionA.clientId) ); }; var createEmpty = createEmpty2; const length = blockAttributes[attributeKeyA].length; if (selectionA.offset === 0 && length) { dispatch.insertBlocks( [createEmpty2()], select.getBlockIndex(selectionA.clientId), anchorRootClientId, false ); return; } if (selectionA.offset === length) { dispatch.insertBlocks( [createEmpty2()], select.getBlockIndex(selectionA.clientId) + 1, anchorRootClientId ); return; } } } const htmlA = blockA.attributes[attributeKeyA]; const htmlB = blockB.attributes[attributeKeyB]; let valueA = create({ html: htmlA }); let valueB = create({ html: htmlB }); valueA = remove(valueA, selectionA.offset, valueA.text.length); valueB = remove(valueB, 0, selectionB.offset); let head = { // Preserve the original client ID. ...blockA, // If both start and end are the same, should only copy innerBlocks // once. innerBlocks: blockA.clientId === blockB.clientId ? [] : blockA.innerBlocks, attributes: { ...blockA.attributes, [attributeKeyA]: toHTMLString({ value: valueA }) } }; let tail = { ...blockB, // Only preserve the original client ID if the end is different. clientId: blockA.clientId === blockB.clientId ? createBlock(blockB.name).clientId : blockB.clientId, attributes: { ...blockB.attributes, [attributeKeyB]: toHTMLString({ value: valueB }) } }; const defaultBlockName = getDefaultBlockName(); if ( // A block is only split when the selection is within the same // block. blockA.clientId === blockB.clientId && defaultBlockName && tail.name !== defaultBlockName && select.canInsertBlockType(defaultBlockName, anchorRootClientId) ) { const switched = switchToBlockType(tail, defaultBlockName); if (switched?.length === 1) { tail = switched[0]; } } if (!blocks.length) { dispatch.replaceBlocks(select.getSelectedBlockClientIds(), [ head, tail ]); return; } let selection; const output = []; const clonedBlocks = [...blocks]; const firstBlock = clonedBlocks.shift(); const headType = getBlockType(head.name); const firstBlocks = headType.merge && firstBlock.name === headType.name ? [firstBlock] : switchToBlockType(firstBlock, headType.name); if (firstBlocks?.length) { const first = firstBlocks.shift(); head = { ...head, attributes: { ...head.attributes, ...headType.merge(head.attributes, first.attributes) } }; output.push(head); selection = { clientId: head.clientId, attributeKey: attributeKeyA, offset: create({ html: head.attributes[attributeKeyA] }).text.length }; clonedBlocks.unshift(...firstBlocks); } else { if (!isUnmodifiedBlock(head)) { output.push(head); } output.push(firstBlock); } const lastBlock = clonedBlocks.pop(); const tailType = getBlockType(tail.name); if (clonedBlocks.length) { output.push(...clonedBlocks); } if (lastBlock) { const lastBlocks = tailType.merge && tailType.name === lastBlock.name ? [lastBlock] : switchToBlockType(lastBlock, tailType.name); if (lastBlocks?.length) { const last = lastBlocks.pop(); output.push({ ...tail, attributes: { ...tail.attributes, ...tailType.merge(last.attributes, tail.attributes) } }); output.push(...lastBlocks); selection = { clientId: tail.clientId, attributeKey: attributeKeyB, offset: create({ html: last.attributes[attributeKeyB] }).text.length }; } else { output.push(lastBlock); if (!isUnmodifiedBlock(tail)) { output.push(tail); } } } else if (!isUnmodifiedBlock(tail)) { output.push(tail); } registry.batch(() => { dispatch.replaceBlocks( select.getSelectedBlockClientIds(), output, output.length - 1, 0 ); if (selection) { dispatch.selectionChange( selection.clientId, selection.attributeKey, selection.offset, selection.offset ); } }); }; var __unstableExpandSelection = () => ({ select, dispatch }) => { const selectionAnchor = select.getSelectionStart(); const selectionFocus = select.getSelectionEnd(); dispatch.selectionChange({ start: { clientId: selectionAnchor.clientId }, end: { clientId: selectionFocus.clientId } }); }; var mergeBlocks = (firstBlockClientId, secondBlockClientId) => ({ registry, select, dispatch }) => { const clientIdA = firstBlockClientId; const clientIdB = secondBlockClientId; const blockA = select.getBlock(clientIdA); const blockAType = getBlockType(blockA.name); if (!blockAType || select.getBlockEditingMode(clientIdA) === "disabled" || select.getBlockEditingMode(clientIdB) === "disabled") { return; } const blockB = select.getBlock(clientIdB); if (!blockAType.merge && getBlockSupport(blockA.name, "__experimentalOnMerge")) { const blocksWithTheSameType2 = switchToBlockType( blockB, blockAType.name ); if (blocksWithTheSameType2?.length !== 1) { dispatch.selectBlock(blockA.clientId); return; } const [blockWithSameType] = blocksWithTheSameType2; if (blockWithSameType.innerBlocks.length < 1) { dispatch.selectBlock(blockA.clientId); return; } registry.batch(() => { dispatch.insertBlocks( blockWithSameType.innerBlocks, void 0, clientIdA ); dispatch.removeBlock(clientIdB); dispatch.selectBlock( blockWithSameType.innerBlocks[0].clientId ); const nextBlockClientId = select.getNextBlockClientId(clientIdA); if (nextBlockClientId && select.getBlockName(clientIdA) === select.getBlockName(nextBlockClientId)) { const rootAttributes = select.getBlockAttributes(clientIdA); const previousRootAttributes = select.getBlockAttributes(nextBlockClientId); if (Object.keys(rootAttributes).every( (key) => rootAttributes[key] === previousRootAttributes[key] )) { dispatch.moveBlocksToPosition( select.getBlockOrder(nextBlockClientId), nextBlockClientId, clientIdA ); dispatch.removeBlock(nextBlockClientId, false); } } }); return; } if (isUnmodifiedDefaultBlock(blockA)) { dispatch.removeBlock( clientIdA, select.isBlockSelected(clientIdA) ); return; } if (isUnmodifiedDefaultBlock(blockB)) { dispatch.removeBlock( clientIdB, select.isBlockSelected(clientIdB) ); return; } if (!blockAType.merge) { if (isUnmodifiedBlock(blockB, "content")) { dispatch.removeBlock( clientIdB, select.isBlockSelected(clientIdB) ); } else { dispatch.selectBlock(blockA.clientId); } return; } const blockBType = getBlockType(blockB.name); const { clientId, attributeKey, offset } = select.getSelectionStart(); const selectedBlockType = clientId === clientIdA ? blockAType : blockBType; const attributeDefinition = selectedBlockType.attributes[attributeKey]; const canRestoreTextSelection = (clientId === clientIdA || clientId === clientIdB) && attributeKey !== void 0 && offset !== void 0 && // We cannot restore text selection if the RichText identifier // is not a defined block attribute key. This can be the case if the // fallback instance ID is used to store selection (and no RichText // identifier is set), or when the identifier is wrong. !!attributeDefinition; if (!attributeDefinition) { if (typeof attributeKey === "number") { window.console.error( `RichText needs an identifier prop that is the block attribute key of the attribute it controls. Its type is expected to be a string, but was ${typeof attributeKey}` ); } else { window.console.error( "The RichText identifier prop does not match any attributes defined by the block." ); } } const cloneA = cloneBlock(blockA); const cloneB = cloneBlock(blockB); if (canRestoreTextSelection) { const selectedBlock = clientId === clientIdA ? cloneA : cloneB; const html = selectedBlock.attributes[attributeKey]; const value = insert( create({ html }), START_OF_SELECTED_AREA, offset, offset ); selectedBlock.attributes[attributeKey] = toHTMLString({ value }); } const blocksWithTheSameType = blockA.name === blockB.name ? [cloneB] : switchToBlockType(cloneB, blockA.name); if (!blocksWithTheSameType || !blocksWithTheSameType.length) { return; } const updatedAttributes = blockAType.merge( cloneA.attributes, blocksWithTheSameType[0].attributes ); if (canRestoreTextSelection) { const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); const convertedHtml = updatedAttributes[newAttributeKey]; const convertedValue = create({ html: convertedHtml }); const newOffset = convertedValue.text.indexOf( START_OF_SELECTED_AREA ); const newValue = remove(convertedValue, newOffset, newOffset + 1); const newHtml = toHTMLString({ value: newValue }); updatedAttributes[newAttributeKey] = newHtml; dispatch.selectionChange( blockA.clientId, newAttributeKey, newOffset, newOffset ); } dispatch.replaceBlocks( [blockA.clientId, blockB.clientId], [ { ...blockA, attributes: { ...blockA.attributes, ...updatedAttributes } }, ...blocksWithTheSameType.slice(1) ], 0 // If we don't pass the `indexToSelect` it will default to the last block. ); }; var removeBlocks = (clientIds, selectPrevious = true) => privateRemoveBlocks(clientIds, selectPrevious); function removeBlock(clientId, selectPrevious) { return removeBlocks([clientId], selectPrevious); } function replaceInnerBlocks(rootClientId, blocks, updateSelection = false, initialPosition = 0) { return { type: "REPLACE_INNER_BLOCKS", rootClientId, blocks, updateSelection, initialPosition: updateSelection ? initialPosition : null, time: Date.now() }; } function toggleBlockMode(clientId) { return { type: "TOGGLE_BLOCK_MODE", clientId }; } function startTyping() { return { type: "START_TYPING" }; } function stopTyping() { return { type: "STOP_TYPING" }; } function startDraggingBlocks(clientIds = []) { return { type: "START_DRAGGING_BLOCKS", clientIds }; } function stopDraggingBlocks() { return { type: "STOP_DRAGGING_BLOCKS" }; } function enterFormattedText() { deprecated('wp.data.dispatch( "core/block-editor" ).enterFormattedText', { since: "6.1", version: "6.3" }); return { type: "DO_NOTHING" }; } function exitFormattedText() { deprecated('wp.data.dispatch( "core/block-editor" ).exitFormattedText', { since: "6.1", version: "6.3" }); return { type: "DO_NOTHING" }; } function selectionChange(clientId, attributeKey, startOffset, endOffset) { if (typeof clientId === "string") { return { type: "SELECTION_CHANGE", clientId, attributeKey, startOffset, endOffset }; } return { type: "SELECTION_CHANGE", ...clientId }; } var insertDefaultBlock = (attributes, rootClientId, index) => ({ dispatch }) => { const defaultBlockName = getDefaultBlockName(); if (!defaultBlockName) { return; } const block = createBlock(defaultBlockName, attributes); return dispatch.insertBlock(block, index, rootClientId); }; function updateBlockListSettings(clientId, settings) { return { type: "UPDATE_BLOCK_LIST_SETTINGS", clientId, settings }; } function updateSettings(settings) { return __experimentalUpdateSettings(settings, { stripExperimentalSettings: true }); } function __unstableSaveReusableBlock(id, updatedId) { return { type: "SAVE_REUSABLE_BLOCK_SUCCESS", id, updatedId }; } function __unstableMarkLastChangeAsPersistent() { return { type: "MARK_LAST_CHANGE_AS_PERSISTENT" }; } function __unstableMarkNextChangeAsNotPersistent() { return { type: "MARK_NEXT_CHANGE_AS_NOT_PERSISTENT" }; } var __unstableMarkAutomaticChange = () => ({ dispatch }) => { dispatch({ type: "MARK_AUTOMATIC_CHANGE" }); const { requestIdleCallback = (cb) => setTimeout(cb, 100) } = window; requestIdleCallback(() => { dispatch({ type: "MARK_AUTOMATIC_CHANGE_FINAL" }); }); }; var __unstableSetEditorMode = (mode) => ({ registry }) => { registry.dispatch(preferencesStore).set("core", "editorTool", mode); if (mode === "navigation") { speak(__("You are currently in Write mode.")); } else if (mode === "edit") { speak(__("You are currently in Design mode.")); } }; function setBlockMovingClientId() { deprecated( 'wp.data.dispatch( "core/block-editor" ).setBlockMovingClientId', { since: "6.7", hint: "Block moving mode feature has been removed" } ); return { type: "DO_NOTHING" }; } var duplicateBlocks = (clientIds, updateSelection = true) => ({ select, dispatch }) => { if (!clientIds || !clientIds.length) { return; } const blocks = select.getBlocksByClientId(clientIds); if (blocks.some((block) => !block)) { return; } const blockNames = blocks.map((block) => block.name); if (blockNames.some( (blockName) => !hasBlockSupport(blockName, "multiple", true) )) { return; } const rootClientId = select.getBlockRootClientId(clientIds[0]); const clientIdsArray = castArray(clientIds); const lastSelectedIndex = select.getBlockIndex( clientIdsArray[clientIdsArray.length - 1] ); const clonedBlocks = blocks.map( (block) => __experimentalCloneSanitizedBlock(block) ); dispatch.insertBlocks( clonedBlocks, lastSelectedIndex + 1, rootClientId, updateSelection ); if (clonedBlocks.length > 1 && updateSelection) { dispatch.multiSelect( clonedBlocks[0].clientId, clonedBlocks[clonedBlocks.length - 1].clientId ); } return clonedBlocks.map((block) => block.clientId); }; var insertBeforeBlock = (clientId) => ({ select, dispatch }) => { if (!clientId) { return; } const rootClientId = select.getBlockRootClientId(clientId); const isLocked = select.getTemplateLock(rootClientId); if (isLocked) { return; } const blockIndex = select.getBlockIndex(clientId); const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; if (!directInsertBlock) { return dispatch.insertDefaultBlock({}, rootClientId, blockIndex); } const copiedAttributes = {}; if (directInsertBlock.attributesToCopy) { const attributes = select.getBlockAttributes(clientId); directInsertBlock.attributesToCopy.forEach((key) => { if (attributes[key]) { copiedAttributes[key] = attributes[key]; } }); } const block = createBlock(directInsertBlock.name, { ...directInsertBlock.attributes, ...copiedAttributes }); return dispatch.insertBlock(block, blockIndex, rootClientId); }; var insertAfterBlock = (clientId) => ({ select, dispatch }) => { if (!clientId) { return; } const rootClientId = select.getBlockRootClientId(clientId); const isLocked = select.getTemplateLock(rootClientId); if (isLocked) { return; } const blockIndex = select.getBlockIndex(clientId); const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; if (!directInsertBlock) { return dispatch.insertDefaultBlock( {}, rootClientId, blockIndex + 1 ); } const copiedAttributes = {}; if (directInsertBlock.attributesToCopy) { const attributes = select.getBlockAttributes(clientId); directInsertBlock.attributesToCopy.forEach((key) => { if (attributes[key]) { copiedAttributes[key] = attributes[key]; } }); } const block = createBlock(directInsertBlock.name, { ...directInsertBlock.attributes, ...copiedAttributes }); return dispatch.insertBlock(block, blockIndex + 1, rootClientId); }; function toggleBlockHighlight(clientId, isHighlighted) { return { type: "TOGGLE_BLOCK_HIGHLIGHT", clientId, isHighlighted }; } var flashBlock = (clientId, timeout = 150) => async ({ dispatch }) => { dispatch(toggleBlockHighlight(clientId, true)); await new Promise((resolve) => setTimeout(resolve, timeout)); dispatch(toggleBlockHighlight(clientId, false)); }; function setHasControlledInnerBlocks(clientId, hasControlledInnerBlocks) { return { type: "SET_HAS_CONTROLLED_INNER_BLOCKS", hasControlledInnerBlocks, clientId }; } function setBlockVisibility(updates) { return { type: "SET_BLOCK_VISIBILITY", updates }; } function __unstableSetTemporarilyEditingAsBlocks(clientId) { deprecated( "wp.data.dispatch( 'core/block-editor' ).__unstableSetTemporarilyEditingAsBlocks", { since: "7.0" } ); return editContentOnlySection(clientId); } var registerInserterMediaCategory = (category) => ({ select, dispatch }) => { if (!category || typeof category !== "object") { console.error( "Category should be an `InserterMediaCategory` object." ); return; } if (!category.name) { console.error( "Category should have a `name` that should be unique among all media categories." ); return; } if (!category.labels?.name) { console.error("Category should have a `labels.name`."); return; } if (!["image", "audio", "video"].includes(category.mediaType)) { console.error( "Category should have `mediaType` property that is one of `image|audio|video`." ); return; } if (!category.fetch || typeof category.fetch !== "function") { console.error( "Category should have a `fetch` function defined with the following signature `(InserterMediaRequest) => Promise<InserterMediaItem[]>`." ); return; } const registeredInserterMediaCategories = select.getRegisteredInserterMediaCategories(); if (registeredInserterMediaCategories.some( ({ name }) => name === category.name )) { console.error( `A category is already registered with the same name: "${category.name}".` ); return; } if (registeredInserterMediaCategories.some( ({ labels: { name } = {} }) => name === category.labels?.name )) { console.error( `A category is already registered with the same labels.name: "${category.labels.name}".` ); return; } dispatch({ type: "REGISTER_INSERTER_MEDIA_CATEGORY", category: { ...category, isExternalResource: true } }); }; function setBlockEditingMode(clientId = "", mode) { return { type: "SET_BLOCK_EDITING_MODE", clientId, mode }; } function unsetBlockEditingMode(clientId = "") { return { type: "UNSET_BLOCK_EDITING_MODE", clientId }; } export { __unstableDeleteSelection, __unstableExpandSelection, __unstableMarkAutomaticChange, __unstableMarkLastChangeAsPersistent, __unstableMarkNextChangeAsNotPersistent, __unstableSaveReusableBlock, __unstableSetEditorMode, __unstableSetTemporarilyEditingAsBlocks, __unstableSplitSelection, clearSelectedBlock, duplicateBlocks, enterFormattedText, exitFormattedText, flashBlock, hideInsertionPoint, hoverBlock, insertAfterBlock, insertBeforeBlock, insertBlock, insertBlocks, insertDefaultBlock, mergeBlocks, moveBlockToPosition, moveBlocksDown, moveBlocksToPosition, moveBlocksUp, multiSelect, receiveBlocks, registerInserterMediaCategory, removeBlock, removeBlocks, replaceBlock, replaceBlocks, replaceInnerBlocks, resetBlocks, resetSelection, selectBlock, selectNextBlock, selectPreviousBlock, selectionChange, setBlockEditingMode, setBlockMovingClientId, setBlockVisibility, setHasControlledInnerBlocks, setTemplateValidity, showInsertionPoint, startDraggingBlocks, startMultiSelect, startTyping, stopDraggingBlocks, stopMultiSelect, stopTyping, synchronizeTemplate, toggleBlockHighlight, toggleBlockMode, toggleSelection, unsetBlockEditingMode, updateBlock, updateBlockAttributes, updateBlockListSettings, updateSettings, validateBlocksToTemplate }; //# sourceMappingURL=actions.js.map