PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / workflows / content / components / UpdatePostConfirm.jsx

UpdatePostConfirm.jsx in Extendify 3.2.1, at src/Agent/workflows/content/components/UpdatePostConfirm.jsx

117 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useCallback, useEffect, useRef } from '@wordpress/element';
2 import { __ } from '@wordpress/i18n';
3
4 export const UpdatePostConfirm = ({ inputs, onConfirm, onCancel, onRetry }) => {
5 const undoTextReplacements = useCallback(() => {
6 const replacements = inputs.replacements || [];
7 const reversed = replacements.map(({ original, updated }) => ({
8 original: updated,
9 updated: original,
10 }));
11 updateAllTextNodesAndAttributes(reversed);
12 }, [inputs]);
13
14 const confirmed = useRef(false);
15 useEffect(() => {
16 return () => {
17 if (!confirmed.current) undoTextReplacements();
18 };
19 }, []);
20
21 const handleConfirm = () => {
22 confirmed.current = true;
23 // The preview patched the DOM, so only a reload shows what was saved.
24 onConfirm({ data: inputs, shouldRefreshPage: true });
25 };
26
27 const handleRetry = useCallback(() => {
28 undoTextReplacements();
29 onRetry();
30 }, [undoTextReplacements, onRetry]);
31
32 useEffect(() => {
33 updateAllTextNodesAndAttributes(inputs.replacements);
34 }, [inputs.replacements]);
35
36 return (
37 <div className="mb-4 ms-2 me-2 flex flex-col rounded-lg border border-gray-300 bg-gray-50">
38 <div className="rounded-lg border-b border-gray-300 bg-white">
39 <div className="p-3">
40 <p className="m-0 p-0 text-sm text-gray-900">
41 {__(
42 'The agent has made the changes in the browser. Please review and confirm.',
43 'extendify-local',
44 )}
45 </p>
46 </div>
47 </div>
48 <div className="flex flex-wrap justify-start gap-2 p-3">
49 <button
50 type="button"
51 className="flex-1 rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
52 onClick={onCancel}
53 >
54 {__('Cancel', 'extendify-local')}
55 </button>
56 <button
57 type="button"
58 className="flex-1 rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
59 onClick={handleRetry}
60 >
61 {__('Try Again', 'extendify-local')}
62 </button>
63 <button
64 type="button"
65 className="flex-1 rounded-sm border border-design-main bg-design-main p-2 text-sm text-white"
66 onClick={handleConfirm}
67 >
68 {__('Save', 'extendify-local')}
69 </button>
70 </div>
71 </div>
72 );
73 };
74
75 const PART_ID_ATTR = 'data-extendify-part-block-id';
76
77 // The save rewrites this post alone, so a part preview reverts on the reload.
78 const isInTemplatePart = (el) => Boolean(el?.closest?.(`[${PART_ID_ATTR}]`));
79
80 const updateAllTextNodesAndAttributes = (replacements) => {
81 const chat = document.getElementById('extendify-agent-chat');
82 const isInChat = (node) => chat?.contains(node);
83 // Update all text nodes
84 const walker = document.createTreeWalker(
85 document.body,
86 NodeFilter.SHOW_TEXT,
87 null,
88 false,
89 );
90 let node = walker.nextNode();
91 while (node) {
92 const current = node;
93 node = walker.nextNode();
94 if (isInChat(current.parentNode)) continue;
95 if (isInTemplatePart(current.parentElement)) continue;
96
97 for (const { original, updated } of replacements ?? []) {
98 const value = current.nodeValue ?? '';
99 if (!value.includes(original)) continue;
100 current.nodeValue = value.split(original).join(updated);
101 }
102 }
103
104 // Update attributes
105 ['alt', 'title', 'aria-label', 'href', 'data-id'].forEach((attr) => {
106 document.querySelectorAll(`[${attr}]`).forEach((el) => {
107 if (isInChat(el)) return;
108 if (isInTemplatePart(el)) return;
109 for (const { original, updated } of replacements ?? []) {
110 const val = el.getAttribute(attr);
111 if (!val?.includes(original)) continue;
112 el.setAttribute(attr, val.split(original).join(updated));
113 }
114 });
115 });
116 };
117