-
Notifications
You must be signed in to change notification settings - Fork 347
/
fragment.js
55 lines (49 loc) · 1.57 KB
/
fragment.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
* Fragment Block
* Include content on a page as a fragment.
* https://www.aem.live/developer/block-collection/fragment
*/
import {
decorateMain,
} from '../../scripts/scripts.js';
import {
loadSections,
} from '../../scripts/aem.js';
/**
* Loads a fragment.
* @param {string} path The path to the fragment
* @returns {HTMLElement} The root element of the fragment
*/
export async function loadFragment(path) {
if (path && path.startsWith('/')) {
const resp = await fetch(`${path}.plain.html`);
if (resp.ok) {
const main = document.createElement('main');
main.innerHTML = await resp.text();
// reset base path for media to fragment base
const resetAttributeBase = (tag, attr) => {
main.querySelectorAll(`${tag}[${attr}^="./media_"]`).forEach((elem) => {
elem[attr] = new URL(elem.getAttribute(attr), new URL(path, window.location)).href;
});
};
resetAttributeBase('img', 'src');
resetAttributeBase('source', 'srcset');
decorateMain(main);
await loadSections(main);
return main;
}
}
return null;
}
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) {
const fragmentSection = fragment.querySelector(':scope .section');
if (fragmentSection) {
block.closest('.section').classList.add(...fragmentSection.classList);
block.closest('.fragment').replaceWith(...fragment.childNodes);
}
}
}