scripts/scripts.js (86 lines of code) (raw):

import { sampleRUM, buildBlock, loadHeader, loadFooter, decorateButtons, decorateIcons, decorateSections, decorateBlocks, decorateTemplateAndTheme, waitForLCP, loadBlocks, loadCSS, wrapImgsInLinks, } from './lib-franklin.js'; const LCP_BLOCKS = []; // add your LCP blocks to the list /** * Builds hero block and prepends to main in a new section. * @param {Element} main The container element */ function buildHeroBlock(main) { const h1 = main.querySelector('h1'); const picture = main.querySelector('picture'); // eslint-disable-next-line no-bitwise if (h1 && picture && (h1.compareDocumentPosition(picture) & Node.DOCUMENT_POSITION_PRECEDING)) { const section = document.createElement('div'); section.append(buildBlock('hero', { elems: [picture, h1] })); main.prepend(section); } } /** * load fonts.css and set a session storage flag */ async function loadFonts() { await loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`); try { if (!window.location.hostname.includes('localhost')) sessionStorage.setItem('fonts-loaded', 'true'); } catch (e) { // do nothing } } /** * Builds all synthetic blocks in a container element. * @param {Element} main The container element */ function buildAutoBlocks(main) { try { buildHeroBlock(main); } catch (error) { // eslint-disable-next-line no-console console.error('Auto Blocking failed', error); } } /** * Decorates the main element. * @param {Element} main The main element */ // eslint-disable-next-line import/prefer-default-export export function decorateMain(main) { wrapImgsInLinks(main); // hopefully forward compatible button decoration decorateButtons(main); decorateIcons(main); buildAutoBlocks(main); decorateSections(main); decorateBlocks(main); } /** * Loads everything needed to get to LCP. * @param {Element} doc The container element */ async function loadEager(doc) { document.documentElement.lang = 'en'; decorateTemplateAndTheme(); const main = doc.querySelector('main'); if (main) { decorateMain(main); document.body.classList.add('appear'); await waitForLCP(LCP_BLOCKS); } try { /* if desktop (proxy for fast connection) or fonts already loaded, load fonts.css */ if (window.innerWidth >= 900 || sessionStorage.getItem('fonts-loaded')) { loadFonts(); } } catch (e) { // do nothing } } /** * Loads everything that doesn't need to be delayed. * @param {Element} doc The container element */ async function loadLazy(doc) { const main = doc.querySelector('main'); await loadBlocks(main); const { hash } = window.location; const element = hash ? doc.getElementById(hash.substring(1)) : false; if (hash && element) element.scrollIntoView(); loadHeader(doc.querySelector('header')); loadFooter(doc.querySelector('footer')); loadCSS(`${window.hlx.codeBasePath}/styles/lazy-styles.css`); loadFonts(); sampleRUM('lazy'); sampleRUM.observe(main.querySelectorAll('div[data-block-name]')); sampleRUM.observe(main.querySelectorAll('picture > img')); } /** * Loads everything that happens a lot later, * without impacting the user experience. */ function loadDelayed() { // eslint-disable-next-line import/no-cycle window.setTimeout(() => import('./delayed.js'), 3000); // load anything that can be postponed to the latest here } async function loadPage() { await loadEager(document); await loadLazy(document); loadDelayed(); } loadPage();