← All changes
|
src/Agent/workflows/block-selector/tools/block-patching.js
+42
-2
3.2.1
→
3.2.2
View file →
| @@ -1,7 +1,10 @@ | ||
| 1 | 1 | import { fetchBlockCodeById } from '@agent/lib/block-code'; |
| 2 | +import { findBlockEl, scopeOf } from '@agent/lib/block-el'; | |
| 2 | 3 | import { applyBlockPatch } from '@agent/lib/block-patch'; |
| 4 | +import { duplicateMarkup } from '@agent/lib/duplicate-block'; | |
| 3 | 5 | import { buildNewBlock } from '@agent/lib/insertable-blocks'; |
| 6 | +import { fetchLinkablePages } from '@agent/lib/linkable-pages'; | |
| 4 | 7 | import { ensureCoreBlocksRegistered } from '@agent/lib/register-blocks'; |
| 5 | 8 | import { swapBlockImage } from '@agent/lib/replace-image'; |
| 6 | 9 | import { SETTING_TEXT_BLOCKS } from '@agent/lib/setting-text-blocks'; |
| 7 | 10 | import { useQuickEditStore } from '@quick-edit/state/store'; |
| @@ -21,15 +24,51 @@ | ||
| 21 | 24 | if (blockCode === previousContent) return null; |
| 22 | 25 | return { op: 'edit', blockId, block: blockCode }; |
| 23 | 26 | }; |
| 24 | 27 | |
| 25 | -const buildAdd = ({ anchorId, position, blockType, patch, clear }) => { | |
| 28 | +const ANCHOR_ROW_CLASS = { 'core/social-link': 'wp-block-social-link' }; | |
| 29 | + | |
| 30 | +const joinsAnchorRow = (anchorId, blockType, source) => { | |
| 31 | + const className = ANCHOR_ROW_CLASS[blockType]; | |
| 32 | + if (!className || anchorId == null) return false; | |
| 33 | + const anchor = findBlockEl(String(anchorId), document, scopeOf({ source })); | |
| 34 | + return Boolean(anchor?.classList?.contains(className)); | |
| 35 | +}; | |
| 36 | + | |
| 37 | +// Unbound, the editor shows a bare custom URL and WP keeps linking a deleted page. | |
| 38 | +const bindPage = async (patch) => { | |
| 39 | + const pages = await fetchLinkablePages(); | |
| 40 | + const page = pages.find(({ url, link }) => [url, link].includes(patch?.url)); | |
| 41 | + return page | |
| 42 | + ? { ...patch, id: page.id, type: 'page', kind: 'post-type' } | |
| 43 | + : patch; | |
| 44 | +}; | |
| 45 | + | |
| 46 | +const buildAdd = async ( | |
| 47 | + { anchorId, position, blockType, patch, clear }, | |
| 48 | + source, | |
| 49 | +) => { | |
| 26 | 50 | const presetSlugs = window.extAgentData?.context?.presetSlugs ?? {}; |
| 27 | - const block = buildNewBlock(blockType, patch, clear ?? [], presetSlugs); | |
| 51 | + const linked = | |
| 52 | + blockType === 'core/navigation-link' ? await bindPage(patch) : patch; | |
| 53 | + const block = buildNewBlock(blockType, linked, clear ?? [], presetSlugs, { | |
| 54 | + joinsRow: joinsAnchorRow(anchorId, blockType, source), | |
| 55 | + }); | |
| 28 | 56 | if (!block) return null; |
| 29 | 57 | return { op: 'add', anchorId, position, block }; |
| 30 | 58 | }; |
| 31 | 59 | |
| 60 | +const buildDuplicate = async (operation, source, postId) => { | |
| 61 | + const { blockId, targetId, position } = operation; | |
| 62 | + const block = await duplicateMarkup(operation, source, postId); | |
| 63 | + return { | |
| 64 | + op: 'duplicate', | |
| 65 | + blockId, | |
| 66 | + ...(targetId && { targetId, position: position ?? 'after' }), | |
| 67 | + ...(block && { block }), | |
| 68 | + }; | |
| 69 | +}; | |
| 70 | + | |
| 32 | 71 | // The backend op has no image — the confirm UI attaches it before the tool runs. |
| 33 | 72 | const buildReplaceImage = async ({ blockId, image }, source, postId) => { |
| 34 | 73 | if (!image) return null; |
| 35 | 74 | const previousContent = await fetchBlockCodeById(blockId, source, postId); |
| @@ -49,8 +88,9 @@ | ||
| 49 | 88 | targetId, |
| 50 | 89 | position, |
| 51 | 90 | }), |
| 52 | 91 | wrap: ({ blockId, container }) => ({ op: 'wrap', blockId, container }), |
| 92 | + duplicate: buildDuplicate, | |
| 53 | 93 | add: buildAdd, |
| 54 | 94 | }; |
| 55 | 95 | |
| 56 | 96 | const writeSetting = (data) => |