PluginProbe
Extendify / 3.1.0
Extendify v3.1.0
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 / QuickEdit / quick-edit.jsx

quick-edit.jsx in Extendify 3.1.0, at src/QuickEdit/quick-edit.jsx

110 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { isEmbedded } from '@shared/lib/embedded-guard';
2 import { dispatch } from '@wordpress/data';
3 import domReady from '@wordpress/dom-ready';
4 import { createRoot, render } from '@wordpress/element';
5 import { InlineEditor } from './components/InlineEditor';
6 import { bindAdminBarToggle } from './lib/admin-bar';
7 import { wireGlobalEscape } from './lib/global-escape';
8 import {
9 attach as attachHoverBar,
10 detach as detachHoverBar,
11 } from './lib/hover-bar';
12 import { attachKeyboardEntry, detachKeyboardEntry } from './lib/keyboard-entry';
13 import {
14 announcePostReload,
15 attachKeyboardUndo,
16 detachKeyboardUndo,
17 } from './lib/keyboard-undo';
18 import { fetchLinkSuggestions } from './lib/link-suggestions';
19 // Side-effect import: subscribes html.extendify-quick-edit-on before first paint.
20 import { useEditModeStore } from './state/edit-mode';
21 import { useQuickEditStore } from './state/store';
22
23 import './quick-edit.css';
24
25 // Cross-bundle race: edit-mode.js is shared with the Agent bundle (via
26 // Chat.jsx + ChatTools.jsx). When the Agent bundle's script tag fires
27 // first, the shared chunk evaluates before this bundle's inline
28 // `window.extQuickEditData = …` has run, so DEFAULT_ON resolves to
29 // false and the store freezes with on=false. By the time THIS module
30 // loads, our `'before'` inline has fired, so re-seed if the server says
31 // defaultOn AND the user has no persisted choice to honor.
32 (() => {
33 if (isEmbedded()) return;
34 if (!window.extQuickEditData?.defaultOn) return;
35 let persisted;
36 try {
37 persisted = JSON.parse(
38 localStorage.getItem('extendify-quick-edit-mode') ?? 'null',
39 );
40 } catch {
41 persisted = null;
42 }
43 if (persisted) return;
44 useEditModeStore.getState().setOn(true);
45 })();
46
47 const App = () => <InlineEditor />;
48
49 const mount = () => {
50 if (!window.extQuickEditData) return;
51 // Never run framed — Customizer preview, multilingual editors, page-builder
52 // previews are all front-end renders, but QE only belongs on the live page.
53 if (isEmbedded()) return;
54
55 const hasTargets =
56 document.querySelector(
57 '[data-extendify-agent-block-id], [data-extendify-part-block-id]',
58 ) !== null;
59 if (!hasTargets) return;
60
61 // The wrapper class is the postcss-prefix-selector scope key (see
62 // `quick-edit` in webpack.config.mjs filePrefixes). Tailwind's preflight +
63 // utilities are all scoped to descendants of `div.extendify-quick-edit`.
64 const host = document.createElement('div');
65 host.id = 'extendify-quick-edit-root';
66 host.className = 'extendify-quick-edit';
67 document.body.appendChild(host);
68
69 if (typeof createRoot === 'function') {
70 createRoot(host).render(<App />);
71 } else {
72 render(<App />, host);
73 }
74
75 bindAdminBarToggle();
76
77 // LinkControl outside our BlockEditorProvider (e.g. NavItemModal in a Modal
78 // portal) needs the global core/block-editor settings hooked too.
79 dispatch('core/block-editor')?.updateSettings({
80 __experimentalFetchLinkSuggestions: fetchLinkSuggestions,
81 });
82
83 // Don't pay the hover/keyboard listener cost when edit mode is off.
84 const getSession = () => !!useQuickEditStore.getState().selected;
85 const apply = (on) => {
86 if (on) {
87 attachHoverBar();
88 attachKeyboardEntry({ getSession });
89 attachKeyboardUndo();
90 } else {
91 detachKeyboardUndo();
92 detachKeyboardEntry();
93 detachHoverBar();
94 }
95 };
96 apply(useEditModeStore.getState().on);
97 useEditModeStore.subscribe((state) => apply(state.on));
98
99 wireGlobalEscape();
100
101 announcePostReload();
102
103 // Toolbar bundle (#3334) dispatches this event so it doesn't need to import our store.
104 window.addEventListener('extendify-quick-edit:toggle', () => {
105 useEditModeStore.getState().toggle();
106 });
107 };
108
109 domReady(mount);
110