Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: try section loader #434

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions blocks/fragment/fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { decorateMain } from '../../scripts/scripts.js';
import { loadBlocks } from '../../scripts/lib-franklin.js';
import { loadSections } from '../../scripts/lib-franklin.js';

/**
* Loads a fragment.
Expand All @@ -19,7 +19,7 @@ async function loadFragment(path) {
const main = document.createElement('main');
main.innerHTML = await resp.text();
decorateMain(main);
await loadBlocks(main);
await loadSections(main);
return main;
}
}
Expand Down
73 changes: 30 additions & 43 deletions scripts/lib-franklin.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,33 +436,6 @@ export function decorateSections(main) {
});
}

/**
* Updates all section status in a container element.
* @param {Element} main The container element
*/
export function updateSectionsStatus(main) {
// NOTE: added div.section to pick up sections that are listed deep
const sections = [
...main.querySelectorAll(':scope > div.section, div.section'),
];
for (let i = 0; i < sections.length; i += 1) {
const section = sections[i];
const status = section.dataset.sectionStatus;
if (status !== 'loaded') {
const loadingBlock = section.querySelector(
'.block[data-block-status="initialized"], .block[data-block-status="loading"]',
);
if (loadingBlock) {
section.dataset.sectionStatus = 'loading';
break;
} else {
section.dataset.sectionStatus = 'loaded';
section.style.display = null;
}
}
}
}

/**
* Decorates all blocks in a container element.
* @param {Element} main The container element
Expand Down Expand Up @@ -578,16 +551,35 @@ export async function loadBlock(block) {
}

/**
* Loads JS and CSS for all blocks in a container element.
* @param {Element} main The container element
* Loads all blocks in a section.
* @param {Element} section The section element
*/
export async function loadBlocks(main) {
updateSectionsStatus(main);
const blocks = [...main.querySelectorAll('div.block')];
for (let i = 0; i < blocks.length; i += 1) {

export async function loadSection(section, loadCallback) {
const status = section.dataset.sectionStatus;
if (status === 'initialized') {
section.dataset.sectionStatus = 'loading';
const blocks = [...section.querySelectorAll('div.block')];
for (let i = 0; i < blocks.length; i += 1) {
// eslint-disable-next-line no-await-in-loop
await loadBlock(blocks[i]);
}
if (loadCallback) await loadCallback(section);
section.dataset.sectionStatus = 'loaded';
section.style.display = null;
}
}

/**
* Loads all sections.
* @param {Element} element The parent element of sections to load
*/

export async function loadSections(element) {
const sections = [...element.querySelectorAll('div.section')];
for (let i = 0; i < sections.length; i += 1) {
// eslint-disable-next-line no-await-in-loop
await loadBlock(blocks[i]);
updateSectionsStatus(main);
await loadSection(sections[i]);
}
}

Expand Down Expand Up @@ -735,15 +727,10 @@ export function decorateButtons(element) {
}

/**
* Load LCP block and/or wait for LCP in default content.
* Wait for Image.
*/
export async function waitForLCP(lcpBlocks) {
const block = document.querySelector('.block');
const hasLCPBlock = block && lcpBlocks.includes(block.dataset.blockName);
if (hasLCPBlock) await loadBlock(block);

document.body.style.display = null;
const lcpCandidate = document.querySelector('main img');
export async function waitForImage(section) {
davidnuescheler marked this conversation as resolved.
Show resolved Hide resolved
const lcpCandidate = section.querySelector('img');
await new Promise((resolve) => {
if (lcpCandidate && !lcpCandidate.complete) {
lcpCandidate.setAttribute('loading', 'eager');
Expand Down
14 changes: 7 additions & 7 deletions scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
toClassName,
decorateSections,
decorateBlocks,
waitForLCP,
loadBlocks,
waitForImage,
loadSection,
loadSections,
loadBlock,
loadCSS,
loadScript,
Expand All @@ -23,8 +24,6 @@ import {
} from '../utils/helpers.js';

// Constants here
const LCP_BLOCKS = ['hero', 'logo-wall']; // add your LCP blocks to the list

const AUDIENCES = {
mobile: () => window.innerWidth < 600,
desktop: () => window.innerWidth >= 600,
Expand Down Expand Up @@ -598,7 +597,8 @@ async function loadEager(doc) {
decorateBreadcrumb(main);
prepareSideNav(main);
document.body.classList.add('appear');
await waitForLCP(LCP_BLOCKS);
const firstSection = main.querySelector('.section');
await loadSection(firstSection, waitForImage);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sometimes wonder if this shouldn't be even implementation details of the responsible block that should await internally before the end of the decoration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would put extra burden on every block that could possibly host the LCP and worry about the distinction of being hosting the LCP and not...

}
}

Expand All @@ -612,7 +612,7 @@ function setUpSoftNavigation() {
const template = dom.querySelector('meta[name="template"]');
if (template && template.getAttribute('content') === 'guides') {
await decorateMain(main);
await loadBlocks(main);
await loadSections(main);
const currentMain = document.querySelector('main');
const children = [...currentMain.children].slice(2);
sampleRUM('leave');
Expand Down Expand Up @@ -672,7 +672,7 @@ async function loadLazy(doc) {
// NOTE:'.redesign' class is needed for the redesign styles, keep this
document.body.classList.add('redesign');

await loadBlocks(main);
await loadSections(main);
addBlockLevelInViewAnimation(main);

const { hash } = window.location;
Expand Down
18 changes: 2 additions & 16 deletions tests/scripts/lib-franklin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,28 +146,14 @@ describe('Sections and blocks', () => {
expect(document.querySelectorAll('main .block').length).to.equal(7);
});

it('Loads blocks', async () => {
it('Loads Sections', async () => {
scripts.init();
await scripts.loadBlocks(document.querySelector('main'));
await scripts.loadSections(document.querySelector('main'));
document.querySelectorAll('main .block').forEach(($block) => {
expect($block.dataset.blockStatus).to.equal('loaded');
});
});

it('Updates section status', async () => {
scripts.updateSectionsStatus(document.querySelector('main'));
document.querySelectorAll('main .section').forEach(($section) => {
expect($section.dataset.sectionStatus).to.equal('loaded');
});

// test section with block still loading
const $section = document.querySelector('main .section');
delete $section.dataset.sectionStatus;
$section.querySelector(':scope .block').dataset.blockStatus = 'loading';
scripts.updateSectionsStatus(document.querySelector('main'));
expect($section.dataset.sectionStatus).to.equal('loading');
});

it('Reads block config', async () => {
document.querySelector('main .section > div').innerHTML += await readFile({
path: './config.html',
Expand Down
Loading