PluginProbe
Extendify / 2.3.1
Extendify v2.3.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 0.7.0 All 126 releases
extendify / src / Library / util / insert.js

insert.js in Extendify 2.3.1, at src/Library/util/insert.js

98 lines 3.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { dispatch, select } from '@wordpress/data';
2 import { useGlobalsStore } from '@library/state/global';
3 import { addGlobalCSS, requiredCSSVars } from '@library/util/css';
4
5 export const insertBlocks = async (blocks) => {
6 const { insertBlocks, replaceBlock } = dispatch('core/block-editor');
7 const {
8 getSelectedBlock,
9 getBlockHierarchyRootClientId,
10 getBlockIndex,
11 getGlobalBlockCount,
12 getBlockParents,
13 getBlock,
14 getBlocks,
15 } = select('core/block-editor');
16
17 const renderingModes =
18 select('core/preferences').get('core', 'renderingModes') || {};
19 const currentTheme = select('core').getCurrentTheme()?.stylesheet;
20 const isTemplateShown =
21 renderingModes?.[currentTheme]?.page === 'template-locked';
22
23 const { set: setPreference } = dispatch('core/preferences');
24 const setRenderingMode = (mode) =>
25 setPreference('core', 'renderingModes', {
26 ...renderingModes,
27 [currentTheme]: { ...(renderingModes[currentTheme] || {}), page: mode },
28 });
29
30 let { clientId, name, attributes } = getSelectedBlock() || {};
31
32 if (clientId && isTemplateShown) {
33 const parentClientIds = getBlockParents(clientId);
34 const parentBlocks = parentClientIds
35 .map((id) => getBlock(id))
36 .filter(Boolean);
37
38 // In "Show Template" mode, the block structure may vary depending on the theme.
39 // Typically, we have something like: <main> → post-content → section/group.
40 // However, themes may introduce intermediate wrappers like group/template-part.
41 // So instead of assuming fixed indexes, we dynamically find the 'core/post-content' (always present)
42 // block among the parents and select the block immediately after it.
43 // This ensures we always get the main section block nested inside post-content.
44 const postContentIndex = parentBlocks.findIndex(
45 (block) => block?.name === 'core/post-content',
46 );
47 const sectionBlockClientId =
48 postContentIndex !== -1
49 ? parentBlocks[postContentIndex + 1]?.clientId || clientId
50 : clientId;
51 const sectionBlockIndex = getBlockIndex(sectionBlockClientId);
52
53 setRenderingMode('post-only');
54 await new Promise((resolve) => requestAnimationFrame(resolve));
55
56 const updatedBlocks = getBlocks();
57 const updatedSelectedBlock = updatedBlocks[sectionBlockIndex];
58 ({ clientId, name, attributes } = updatedSelectedBlock || {});
59 }
60
61 const rootClientId = clientId ? getBlockHierarchyRootClientId(clientId) : '';
62 const insertPointIndex =
63 (rootClientId ? getBlockIndex(rootClientId) : getGlobalBlockCount()) + 1;
64
65 // If there are spacing vars in state, we need to add them to the dom
66 const { missingCSSVars } = useGlobalsStore.getState();
67 missingCSSVars.forEach((key) => {
68 // Add variables to the dom
69 document?.documentElement?.style?.setProperty(key, requiredCSSVars[key]);
70 // Editor might be nested in an iframe too
71 document
72 .querySelector('iframe[name="editor-canvas"]')
73 ?.contentDocument?.documentElement?.style?.setProperty(
74 key,
75 requiredCSSVars[key],
76 );
77 });
78
79 // We also need to add them to global styles too
80 if (missingCSSVars.length) addGlobalCSS(missingCSSVars);
81
82 try {
83 // Ensure showTemplate is off even if no block was selected above
84 if (isTemplateShown && !clientId) {
85 setRenderingMode('post-only');
86 await new Promise((resolve) => requestAnimationFrame(resolve));
87 }
88
89 if (name === 'core/paragraph' && attributes?.content?.text === '') {
90 return await replaceBlock(clientId, blocks);
91 }
92
93 return await insertBlocks(blocks, insertPointIndex);
94 } finally {
95 if (isTemplateShown) setRenderingMode('template-locked');
96 }
97 };
98