diff --git a/blocks/fragment/fragment.js b/blocks/fragment/fragment.js index fc79950..a2271e7 100644 --- a/blocks/fragment/fragment.js +++ b/blocks/fragment/fragment.js @@ -46,5 +46,19 @@ export default async function decorate(block) { const link = block.querySelector('a'); const path = link ? link.getAttribute('href') : block.textContent.trim(); const fragment = await loadFragment(path); - if (fragment) block.replaceChildren(...fragment.childNodes); + if (!fragment) return; + + const wrapper = block.closest('.fragment-wrapper'); + const section = wrapper.closest('.section'); + + if (section && section.children.length === 1) { + // fragment is the ONLY child of its section; replace the whole section + section.replaceWith(...fragment.childNodes); + } else { + // fragment shares section with other children; flatten blocks into it + fragment.querySelectorAll(':scope > .section').forEach((fragSection) => { + [...fragSection.childNodes].forEach((child) => wrapper.before(child)); + }); + wrapper.remove(); + } } diff --git a/scripts/scripts.js b/scripts/scripts.js index a3c48e6..2c90619 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -153,24 +153,13 @@ function buildVideoAutoBlocks(main) { * @param {Element} main The container element */ function buildFragmentAutoBlocks(main) { - const fragments = [...main.querySelectorAll('a[href*="/fragments/"]')].filter((f) => !f.closest('.fragment')); - if (!fragments.length) return; - // hide containers immediately so raw links never flash before replacement - fragments.forEach((f) => { f.parentElement.style.visibility = 'hidden'; }); - // eslint-disable-next-line import/no-cycle - import('../blocks/fragment/fragment.js').then(({ loadFragment }) => { - fragments.forEach(async (fragment) => { - try { - const { pathname } = new URL(fragment.href); - const frag = await loadFragment(pathname); - fragment.parentElement.replaceWith(...frag.children); - } catch (error) { - fragment.parentElement.style.visibility = ''; - // eslint-disable-next-line no-console - console.error('Fragment loading failed', error); - } + [...main.querySelectorAll('a[href*="/fragments/"]')] + .filter((f) => !f.closest('.fragment')) + .forEach((link) => { + const fragmentBlock = buildBlock('fragment', { elems: [link.cloneNode(true)] }); + const p = link.closest('p'); + (p || link).replaceWith(fragmentBlock); }); - }); } /**