Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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/anchor-nav/anchor-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default function decorate(block) {
e.preventDefault();
const target = document.getElementById(href.substring(1));
if (target) {
// Swapna: Move active class to clicked link for red underline
// Move active class to clicked link for red underline
block.querySelectorAll('.anchor-nav-link:not(.primary, .secondary)').forEach((l) => l.classList.remove('active'));
link.classList.add('active');

Expand All @@ -100,7 +100,7 @@ export default function decorate(block) {
});
});

// Swapna: Set first anchor link as active by default on page load
// Set first anchor link as active by default on page load
const firstAnchorLink = block.querySelector('.anchor-nav-link:not(.primary, .secondary)');
if (firstAnchorLink) {
firstAnchorLink.classList.add('active');
Expand Down
2 changes: 0 additions & 2 deletions blocks/footer/footer.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
footer {
font-size: var(--body-font-size-xs);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}

.footer a {
Expand Down Expand Up @@ -188,7 +187,6 @@ footer .footer>div .section>div {
.footer>div>div .accordion-wrapper .accordion .accordion-item-body ul li {
margin-top: var(--spacing-xs);
list-style: none;
line-height: 1;
}

.footer>div>div .accordion-wrapper .accordion>div>div:nth-child(2) ul li a,
Expand Down
32 changes: 24 additions & 8 deletions blocks/hero-heritage-cc/hero-heritage-cc.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/* Section container - fixed height to prevent CLS */
.hero-heritage-cc-container {
position: relative;
min-height: calc(100vh - var(--spacing-xl)); /* fallback for older browsers */
min-height: calc(100dvh - var(--spacing-xl));
height: calc(100vh - var(--spacing-xl));
height: calc(100dvh - var(--spacing-xl));
contain: strict;
overflow: hidden;
}
Expand Down Expand Up @@ -492,6 +488,7 @@ color: var(--color-pewter);
.hero-heritage-cc p.hero-heritage-cc-banner-image {
margin: 10px 0 0;
transition: opacity 0.35s ease-out, transform 0.35s ease-out;
min-height: 226px;
}

.hero-heritage-cc .hero-heritage-cc-banner {
Expand All @@ -518,6 +515,11 @@ color: var(--color-pewter);
.hero-heritage-cc p {
font-size: var(--body-font-size-m);
}

.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-hindi,
.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-english {
min-height: 133px;
}
}

/* Desktop: 900px and up */
Expand All @@ -536,6 +538,18 @@ color: var(--color-pewter);
display: flex;
}

/* Logo images at native size with reserved space to prevent CLS */
.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-hindi picture,
.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-english picture {
min-height: 252px;
}

.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-hindi img,
.hero-heritage-cc-intro .hero-heritage-cc-intro-logo-english img {
width: auto;
min-height: 252px;
}

.hero-heritage-cc .hero-heritage-cc-banner-cta-group {
margin-top: var(--spacing-l);
}
Expand All @@ -544,6 +558,10 @@ color: var(--color-pewter);
font-size: var(--body-font-size-s);
}

.hero-heritage-cc p.hero-heritage-cc-banner-image {
min-height: 291px;
}

.hero-heritage-cc-banner-cta .button {
font-size: var(--body-font-size-l);
}
Expand All @@ -558,10 +576,8 @@ color: var(--color-pewter);
}

.hero-heritage-cc-container {
min-height: calc(100vh - 120px);
min-height: calc(100dvh - 120px);
height: calc(100vh - 120px);
height: calc(100dvh - 120px);
height: 100%;
width: 100%;
}

/* Decoration image - top right */
Expand Down
33 changes: 16 additions & 17 deletions blocks/hero-heritage-cc/hero-heritage-cc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { decorateButtons } from '../../scripts/aem.js';
import { decorateButtons, pickPicturePreloadUrl } from '../../scripts/aem.js';
import { loadFragment } from '../../scripts/scripts.js';

/* eslint-disable secure-coding/no-hardcoded-credentials -- CSS classes/style props only */
Expand Down Expand Up @@ -107,6 +107,18 @@ function decorateHeaderCta(block, row) {
decorateButtons(row);
}

/** Insert hero intro image preload if missing (href must match viewport-selected picture). */
function appendHeroIntroImagePreload(href, matchedWebpSource) {
if (document.querySelector(`head > link[rel="preload"][as="image"][href="${href}"]`)) return;
const preloadLink = document.createElement('link');
preloadLink.rel = 'preload';
preloadLink.as = 'image';
preloadLink.href = href;
preloadLink.fetchPriority = 'high';
if (matchedWebpSource || href.includes('format=webply')) preloadLink.type = 'image/webp';
document.head.insertBefore(preloadLink, document.head.firstChild);
}

/** Apply background image from first picture to section (or UE preview). Uses an img for LCP. */
function applyIntroBackground(block, introContent, pictures) {
const bgPicture = pictures[0];
Expand All @@ -122,11 +134,8 @@ function applyIntroBackground(block, introContent, pictures) {
return;
}

const webpSource = bgPicture.querySelector('source[type="image/webp"]');
let bgUrl = webpSource?.srcset?.split(',')[0]?.trim()?.split(' ')[0] || bgImg?.src;
if (bgUrl?.includes('optimize=medium')) {
bgUrl = bgUrl.replace('optimize=medium', 'optimize=large');
}
const { url: bgUrlRaw, source: matchedWebpSource } = pickPicturePreloadUrl(bgPicture, 'image/webp');
const bgUrl = bgUrlRaw || bgImg?.src || '';

const sectionContainer = block.closest('.section');
if (!sectionContainer || !bgUrl) {
Expand All @@ -135,17 +144,7 @@ function applyIntroBackground(block, introContent, pictures) {
return;
}

/* Preload only if not already added by scripts.js (early LCP preload) */
const existingPreload = document.querySelector(`head > link[rel="preload"][as="image"][href="${bgUrl}"]`);
if (!existingPreload) {
const preloadLink = document.createElement('link');
preloadLink.rel = 'preload';
preloadLink.as = 'image';
preloadLink.href = bgUrl;
preloadLink.fetchPriority = 'high';
if (webpSource) preloadLink.type = 'image/webp';
document.head.insertBefore(preloadLink, document.head.firstChild);
}
appendHeroIntroImagePreload(bgUrl, matchedWebpSource);

/* Keep an img in the DOM as the LCP element (better than CSS background for PageSpeed) */
const layer = document.createElement('div');
Expand Down
47 changes: 16 additions & 31 deletions blocks/hotspot/hotspot.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
/* Prevent CLS: hide until fully decorated, reserve space */
.hotspot:not([data-block-status="loaded"]) {
visibility: hidden;
min-height: 400px;
}

/* Two-column layout */
Expand All @@ -17,7 +16,6 @@
align-items: stretch;
justify-self: start;
margin: 0 auto;
min-height: 400px;
position: relative;
transition: opacity 0.1s ease;
}
Expand Down Expand Up @@ -227,38 +225,9 @@
opacity: 1;
}

/* Responsive adjustments */
@media (width <= 1024px) {
.hotspot:not([data-block-status="loaded"]) {
min-height: 350px;
}

.hotspot-container {
min-height: 350px;
}

.hotspot-tooltip-panel {
flex: 0 0 35%;
padding: 30px;
}

.hotspot-tooltip-content {
font-size: 16px;
}

.hotspot-image-section {
flex: 0 0 65%;
}
}

@media (width <= 768px) {
.hotspot:not([data-block-status="loaded"]) {
min-height: 350px;
}

.hotspot-container {
flex-direction: column;
min-height: 350px;
}

.hotspot-tooltip-panel {
Expand All @@ -285,6 +254,22 @@
}
}

/* Responsive adjustments */
@media (width <= 1024px) {
.hotspot-tooltip-panel {
flex: 0 0 35%;
padding: 30px;
}

.hotspot-tooltip-content {
font-size: 16px;
}

.hotspot-image-section {
flex: 0 0 65%;
}
}

/* Hide empty panel */
.hotspot-tooltip-panel:not(.visible) {
pointer-events: none;
Expand Down
13 changes: 6 additions & 7 deletions head.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<!-- https://www.aem.live/docs/csp-strict-dynamic-cached-nonce -->
<!-- https://www.aem.live/docs/csp-strict-dynamic-cached-nonce
<meta
http-equiv="Content-Security-Policy"
content="script-src 'nonce-aem' 'strict-dynamic' 'unsafe-inline' http: https:; base-uri 'self'; object-src 'none';"
move-to-http-header="true"
>
move-to -->
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="/scripts/swiperjs/swiper-bundle.min.css"/>
<script nonce="aem" src="/scripts/swiperjs/swiper-bundle.min.js"></script>
<script nonce="aem" src="/scripts/aem.js" type="module"></script>
<script nonce="aem" src="/scripts/scripts.js" type="module"></script>
<script src="/scripts/aem.js" type="module"></script>
<script src="/scripts/scripts.js" type="module"></script>
<link rel="stylesheet" href="/styles/styles.css"/>
<link rel="stylesheet" href="/scripts/swiperjs/swiper-bundle.min.css"/>
<script src="/scripts/swiperjs/swiper-bundle.min.js"></script>
<meta name="urn:adobe:aue:config:preview" content="main--idfc-edge--aemsites.aem.page"/>
38 changes: 38 additions & 0 deletions scripts/aem.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,43 @@ function createOptimizedPicture(
return picture;
}

/** Cap <source> scans (legitimate pictures use few sources; limits loop work for CWE-400). */
const MAX_PICTURE_SOURCES_PRELOAD = 64;

/**
* First matching <source> URL for type + media (document order), else <img> src.
* Matches browser <picture> behavior so preloads use the same URL as the chosen art direction
* (e.g. width=750 on mobile vs width=2000 for (min-width: 600px)).
* @param {HTMLPictureElement} picture
* @param {string} [typePrefix] e.g. image/webp
* @returns {{ url: string, source: Element|null, img: HTMLImageElement|null }}
*/
function pickPicturePreloadUrl(picture, typePrefix = 'image/webp') {
const needle = typePrefix.toLowerCase();
const img = picture?.querySelector('img') ?? null;
if (!picture) {
return { url: '', source: null, img };
}
const sources = picture.querySelectorAll('source');
const n = Math.min(sources.length, MAX_PICTURE_SOURCES_PRELOAD);
for (let i = 0; i < n; i += 1) {
const source = sources[i];
const t = (source.getAttribute('type') || '').toLowerCase();
if (t.startsWith(needle)) {
const media = source.getAttribute('media');
if (!media || window.matchMedia(media).matches) {
const srcset = source.getAttribute('srcset');
if (srcset) {
const url = srcset.split(',')[0].trim().split(/\s+/)[0];
if (url) return { url, source, img };
}
}
}
}
const fallback = img?.getAttribute('src') || img?.src || '';
return { url: fallback, source: null, img };
}

/**
* Set template (page structure) and theme (page styles).
*/
Expand Down Expand Up @@ -787,6 +824,7 @@ export {
loadScript,
loadSection,
loadSections,
pickPicturePreloadUrl,
readBlockConfig,
sampleRUM,
setup,
Expand Down
Loading
Loading