import { useCallback, useEffect, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
export const UpdatePostConfirm = ({ inputs, onConfirm, onCancel, onRetry }) => {
const undoTextReplacements = useCallback(() => {
const replacements = inputs.replacements || [];
const reversed = replacements.map(({ original, updated }) => ({
original: updated,
updated: original,
}));
updateAllTextNodesAndAttributes(reversed);
}, [inputs]);
const confirmed = useRef(false);
useEffect(() => {
return () => {
if (!confirmed.current) undoTextReplacements();
};
}, []);
const handleConfirm = () => {
confirmed.current = true;
onConfirm({ data: inputs });
};
const handleRetry = useCallback(() => {
undoTextReplacements();
onRetry();
}, [undoTextReplacements, onRetry]);
useEffect(() => {
updateAllTextNodesAndAttributes(inputs.replacements);
}, [inputs.replacements]);
return (
{__(
'The agent has made the changes in the browser. Please review and confirm.',
'extendify-local',
)}
);
};
const updateAllTextNodesAndAttributes = (replacements) => {
const chat = document.getElementById('extendify-agent-chat');
const isInChat = (node) => chat?.contains(node);
// Update all text nodes
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false,
);
let node = walker.nextNode();
while (node) {
const current = node;
node = walker.nextNode();
// Skip nodes that are inside the chat
if (isInChat(current.parentNode)) continue;
for (const { original, updated } of replacements ?? []) {
const value = current.nodeValue ?? '';
if (!value.includes(original)) continue;
current.nodeValue = value.split(original).join(updated);
}
}
// Update attributes
['alt', 'title', 'aria-label', 'href', 'data-id'].forEach((attr) => {
document.querySelectorAll(`[${attr}]`).forEach((el) => {
// Skip elements that are inside the chat
if (isInChat(el)) return;
for (const { original, updated } of replacements ?? []) {
const val = el.getAttribute(attr);
if (!val?.includes(original)) continue;
el.setAttribute(attr, val.split(original).join(updated));
}
});
});
};