PluginProbe
Extendify / trunk
Extendify vtrunk
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
← All changes | src/Agent/components/DOMHighlighter.jsx +12 -23 3.1.5 → trunk View file →
@@ -1,5 +1,7 @@
1 1 import { usePortal } from '@agent/hooks/usePortal';
2 +import { blockCodeQueryArgs } from '@agent/lib/block-code';
3 +import { findBlockEl, scopeOf } from '@agent/lib/block-el';
2 4 import { useWorkflowStore } from '@agent/state/workflows';
3 5 import { whenAnimationsSettle } from '@quick-edit/lib/after-animations';
4 6 import { MEDIA_RING, needsContrastRing } from '@quick-edit/lib/over-media';
5 7 import { useQuickEditStore } from '@quick-edit/state/store';
@@ -42,14 +44,13 @@
42 44
43 45 useEffect(() => {
44 46 if (!block?.id) return;
45 47 const ac = new AbortController();
46 - const postId = window.extAgentData?.context?.postId;
47 - if (!postId) return;
48 - const queryArgs = {
49 - postId: String(postId),
50 - blockId: String(block.id),
51 - };
48 + const queryArgs = blockCodeQueryArgs(
49 + block,
50 + window.extAgentData?.context?.postId,
51 + );
52 + if (!queryArgs) return;
52 53
53 54 const isAlive = { current: true };
54 55 (async () => {
55 56 const res = await apiFetch({
@@ -68,12 +69,9 @@
68 69 // Re-syncs the rect for programmatic block changes (e.g. Ask AI)
69 70 // and after the wp-site-blocks open/close transform settles.
70 71 useEffect(() => {
71 72 if (!block?.id) return;
72 - const attr = block.target || 'data-extendify-agent-block-id';
73 - const match = document.querySelector(
74 - `[${attr}="${CSS.escape(String(block.id))}"]`,
75 - );
73 + const match = findBlockEl(block.id, document, scopeOf(block));
76 74 if (!match) return;
77 75 el.current = match;
78 76 setRingNeeded(needsContrastRing(match));
79 77
@@ -124,13 +122,10 @@
124 122 }, []);
125 123
126 124 useEffect(() => {
127 125 if (!block?.id) return;
128 - const attr = block.target || 'data-extendify-agent-block-id';
129 126 const handle = () => {
130 - const match = document.querySelector(
131 - `[${attr}="${CSS.escape(String(block.id))}"]`,
132 - );
127 + const match = findBlockEl(block.id, document, scopeOf(block));
133 128 // Clearing only the rect leaves the chip counting a gone node.
134 129 if (!match) {
135 130 clearBlock();
136 131 return;
@@ -189,20 +184,14 @@
189 184 resizeObserver.disconnect();
190 185 };
191 186 }, [el.current]);
192 187
193 - // Workflows can mutate the page while the outline is up: a tool that
194 - // re-renders the block produces a new DOM node with the same
195 - // data-extendify-agent-block-id, and ancestor reflows can shift the
196 - // element without changing its own size (ResizeObserver misses both).
197 - // Re-query and re-measure on any wp-site-blocks subtree mutation,
198 - // rAF-debounced so a burst of mutations costs one measurement.
188 + // ResizeObserver misses a replaced node and an ancestor reflow, so the
189 + // outline stays on the old box.
199 190 useEffect(() => {
200 191 if (!block?.id) return;
201 192 const root = document.querySelector('.wp-site-blocks');
202 193 if (!root) return;
203 - const attr = block.target || 'data-extendify-agent-block-id';
204 - const sel = `[${attr}="${CSS.escape(String(block.id))}"]`;
205 194
206 195 let rafId = 0;
207 196 const observer = new MutationObserver(() => {
208 197 if (rafId) return;
@@ -207,9 +196,9 @@
207 196 const observer = new MutationObserver(() => {
208 197 if (rafId) return;
209 198 rafId = window.requestAnimationFrame(() => {
210 199 rafId = 0;
211 - const match = document.querySelector(sel);
200 + const match = findBlockEl(block.id, document, scopeOf(block));
212 201 if (!match) return;
213 202 el.current = match;
214 203 const r = match.getBoundingClientRect();
215 204 if (r.width <= 0 || r.height <= 0) return;