| 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 |
|