diff --git a/libs/blocks/global-navigation/global-navigation.js b/libs/blocks/global-navigation/global-navigation.js index 00aac8aace..74181e5ea7 100644 --- a/libs/blocks/global-navigation/global-navigation.js +++ b/libs/blocks/global-navigation/global-navigation.js @@ -316,6 +316,11 @@ const convertToPascalCase = (str) => str .map((s) => s.charAt(0).toUpperCase() + s.slice(1)) .join(' '); +const removeLocalNav = () => { + lanaLog({ message: 'Gnav Localnav was removed, potential CLS', tags: 'gnav-localnav' }); + document.querySelector('.feds-localnav')?.remove(); +}; + class Gnav { constructor({ content, block, newMobileNav } = {}) { this.content = content; @@ -428,9 +433,12 @@ class Gnav { }; decorateLocalNav = async () => { - if (!this.isLocalNav()) return; + if (!this.isLocalNav()) { + removeLocalNav(); + return; + } const localNavItems = this.elements.navWrapper.querySelector('.feds-nav').querySelectorAll('.feds-navItem:not(.feds-navItem--section, .feds-navItem--mobile-only)'); - const firstElem = localNavItems[0]?.querySelector('a'); + const firstElem = localNavItems[0]?.querySelector('a') || localNavItems[0]?.querySelector('button'); if (!firstElem) { lanaLog({ message: 'GNAV: Incorrect authoring of localnav found.', tags: 'gnav', errorType: 'info' }); return; @@ -454,7 +462,11 @@ class Gnav { localNavItems.forEach((elem, idx) => { const clonedItem = elem.cloneNode(true); - const link = clonedItem.querySelector('a'); + const link = clonedItem.querySelector('a, button'); + + if (link) { + link.dataset.title = link.textContent; + } if (idx === 0) { localNav.querySelector('.feds-localnav-title').innerText = title.trim(); @@ -477,7 +489,7 @@ class Gnav { const promo = document.querySelector('.feds-promo-aside-wrapper'); if (promo) localNav.classList.add('has-promo'); this.elements.localNav = localNav; - localNavItems[0].querySelector('a').textContent = title.trim(); + firstElem.textContent = title.trim(); const isAtTop = () => { const rect = this.elements.localNav.getBoundingClientRect(); // note: ios safari changes between -0.34375, 0, and 0.328125 @@ -1115,10 +1127,18 @@ class Gnav { // Copying dropdown contents to localNav items const decorateLocalNavItems = (navItem, template) => { const elements = [...document.querySelectorAll('.feds-localnav .feds-navItem')].find( - (el) => el.textContent.trim() === navItem.textContent, + (el) => { + const link = el.querySelector('a, button'); + return link.dataset.title?.trim() === navItem.textContent; + }, ); if (elements) { + const dropdownBtn = elements.querySelector('button'); elements.innerHTML = template.innerHTML; + // To override the textcontent of button of first item of localnav + if (dropdownBtn) { + elements.querySelector('button').textContent = dropdownBtn.textContent; + } // Reattach click events & mutation observers, as cloned elem don't retain event listeners elements.querySelector('.feds-localnav-items button')?.addEventListener('click', (e) => { trigger({ element: e.currentTarget, event: e, type: 'localNavItem' }); diff --git a/test/navigation/bootstrapper.test.js b/test/navigation/bootstrapper.test.js index 1d1d00f5f6..3f69a4f2a4 100644 --- a/test/navigation/bootstrapper.test.js +++ b/test/navigation/bootstrapper.test.js @@ -7,6 +7,7 @@ import fetchedFooter from '../blocks/global-footer/mocks/fetched-footer.js'; import placeholders from '../blocks/global-navigation/mocks/placeholders.js'; import { setConfig } from '../../libs/utils/utils.js'; import { mockRes } from '../blocks/global-navigation/test-utilities.js'; +import gnavLocalNav from './mocks/gnav-with-localnav.plain.js'; const blockConfig = { footer: { @@ -36,6 +37,7 @@ describe('Bootstrapper', async () => { ), }); } + if (url.includes('/localnav/gnav.plain.html')) return mockRes({ payload: gnavLocalNav }); if (url.includes('/placeholders')) return mockRes({ payload: placeholders }); if (url.includes('/footer.plain.html')) return mockRes({ payload: await readFile({ path: '../blocks/region-nav/mocks/regions.html' }) }); if (url.includes('/gnav.plain.html')) return mockRes({ payload: await readFile({ path: './mocks/gnav.html' }) }); @@ -95,6 +97,7 @@ describe('Bootstrapper', async () => { it('Renders the localnav', async () => { blockConfig.header.isLocalNav = true; blockConfig.header.mobileGnavV2 = true; + setConfig({ contentRoot: '/federal/localnav' }); const { default: init } = await import('../../libs/blocks/global-navigation/global-navigation.js'); await loadBlock(init, blockConfig.header); const el = document.querySelector('header'); diff --git a/test/navigation/mocks/gnav-with-localnav.plain.js b/test/navigation/mocks/gnav-with-localnav.plain.js new file mode 100644 index 0000000000..bae6eb2e0f --- /dev/null +++ b/test/navigation/mocks/gnav-with-localnav.plain.js @@ -0,0 +1,70 @@ +export default ` +
+
+