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
← All changes | src/QuickEdit/lib/keyboard-entry.js +16 -49 3.1.23.2.1 View file →
@@ -1,13 +1,8 @@
1 1 import { __, sprintf } from '@wordpress/i18n';
2 +import { useQuickEditStore } from '../state/store';
2 3 import { resolveTarget } from './dom';
3 -import {
4 - askAiTarget,
5 - editTarget,
6 - hideBar,
7 - pillContextFor,
8 - showBar,
9 -} from './hover-bar';
4 +import { hideBar, isAgentWorking, pinTarget, showBar } from './hover-bar';
10 5
11 6 const SELECTOR = [
12 7 '[data-extendify-agent-block-id]',
13 8 '[data-extendify-part-block-id]',
@@ -34,34 +29,19 @@
34 29 }
35 30 return null;
36 31 };
37 32
38 -const buildAriaLabel = (el, target, { quickEditable, aiAvailable }) => {
33 +// Enter only reveals the pills, so announcing "Edit" promises too much.
34 +const buildAriaLabel = (el) => {
39 35 const text = (el.textContent || '').trim().replace(/\s+/g, ' ');
40 36 const snippet = text.length > 60 ? `${text.substring(0, 60)}…` : text;
41 - // Ask-AI-only blocks (group / columns / media-text) route Enter to the
42 - // agent, so announce that action rather than "Edit".
43 - if (aiAvailable && !quickEditable) {
44 - return snippet
45 - ? sprintf(
46 - // translators: %s is a snippet of the block's text content.
47 - __('Ask AI about "%s"', 'extendify-local'),
48 - snippet,
49 - )
50 - : __('Ask AI', 'extendify-local');
51 - }
52 - const verb =
53 - target?.blockType === 'core/image' || target?.blockType === 'core/cover'
54 - ? __('Replace image', 'extendify-local')
55 - : __('Edit', 'extendify-local');
56 37 return snippet
57 38 ? sprintf(
58 - // translators: %1$s is the action verb (Edit / Replace image), %2$s is a snippet of the block's text content.
59 - __('%1$s "%2$s"', 'extendify-local'),
60 - verb,
39 + // translators: %s is a snippet of the block's text content.
40 + __('Editing options for "%s"', 'extendify-local'),
61 41 snippet,
62 42 )
63 - : verb;
43 + : __('Editing options', 'extendify-local');
64 44 };
65 45
66 46 // Skips role="button" on headings/links/landmarks so SR users
67 47 // retain heading/link/landmark navigation. Enter/Space still
@@ -98,13 +78,9 @@
98 78 if (!isHeading && !isLink && !isLandmark) {
99 79 el.setAttribute('role', 'button');
100 80 }
101 81
102 - const target = resolveTarget(el);
103 - el.setAttribute(
104 - 'aria-label',
105 - buildAriaLabel(el, target, pillContextFor(target)),
106 - );
82 + el.setAttribute('aria-label', buildAriaLabel(el));
107 83 el.setAttribute(KB_READY_ATTR, '1');
108 84 }
109 85 };
110 86
@@ -133,8 +109,9 @@
133 109 decorate();
134 110
135 111 onFocusIn = (e) => {
136 112 if (getSession?.()) return;
113 + if (isAgentWorking()) return;
137 114 const el = findTagged(e.target);
138 115 if (!el) return;
139 116 hideBar();
140 117 showBar(el);
@@ -160,13 +137,17 @@
160 137 ) {
161 138 return;
162 139 }
163 140 if (target && !document.body.contains(target)) return;
141 + // A pinned bar outlives focus; only an outside click or Esc drops it.
142 + if (useQuickEditStore.getState().committedSelection) return;
164 143 const active = document.activeElement;
165 144 if (!active || active === document.body) {
166 145 hideBar();
167 146 return;
168 147 }
148 + // Pinning moves focus onto a pill, which lives outside the block.
149 + if (active.closest?.('.extendify-quick-edit-bar')) return;
169 150 if (findTagged(active)) return;
170 151 hideBar();
171 152 }, 0);
172 153 };
@@ -173,31 +154,17 @@
173 154
174 155 onActivate = (e) => {
175 156 if (e.key !== 'Enter' && e.key !== ' ') return;
176 157 if (getSession?.()) return;
158 + if (isAgentWorking()) return;
177 159 const el = findTagged(e.target);
178 160 if (!el) return;
179 161 // Skip activation when the keystroke came from a child with
180 162 // its own action (e.g. a link inside a nav item).
181 163 if (e.target !== el) return;
182 - const target = resolveTarget(el);
183 - if (!target?.blockType) return;
164 + if (!resolveTarget(el)?.blockType) return;
184 165 e.preventDefault();
185 - const { quickEditable, aiAvailable } = pillContextFor(target);
186 - // Quick-editable blocks open the inline editor (picker types need the
187 - // bar mounted first so the dropdown can anchor to it).
188 - if (quickEditable) {
189 - showBar(el);
190 - editTarget(target);
191 - return;
192 - }
193 - // Ask-AI-only blocks (group / columns / media-text) have no editor to
194 - // open; route Enter straight to the agent like the Ask AI pill does.
195 - if (aiAvailable) {
196 - askAiTarget(el);
197 - return;
198 - }
199 - showBar(el);
166 + pinTarget(el);
200 167 };
201 168
202 169 document.addEventListener('focusin', onFocusIn, true);
203 170 document.addEventListener('focusout', onFocusOut, true);