From ca9068a6cdc1ce2f93b6d63eaa13eff978d6d376 Mon Sep 17 00:00:00 2001
From: Max Edell <maxed@adobe.com>
Date: Wed, 18 Oct 2023 17:49:20 -0700
Subject: [PATCH] fix: defer carousel images

---
 blocks/resources/resources.css |  4 ++
 blocks/resources/resources.js  | 76 +++++++++++++++++++---------------
 2 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/blocks/resources/resources.css b/blocks/resources/resources.css
index 8c8a446..69aad6a 100644
--- a/blocks/resources/resources.css
+++ b/blocks/resources/resources.css
@@ -11,3 +11,7 @@
 .resources-container .default-content-wrapper h4 {
   color: var(--landing-heading-color);
 }
+
+.resources.block:not(.in-view) .splide__slide a {
+  background: none!important;
+}
\ No newline at end of file
diff --git a/blocks/resources/resources.js b/blocks/resources/resources.js
index 0e0034b..9c42656 100644
--- a/blocks/resources/resources.js
+++ b/blocks/resources/resources.js
@@ -1,5 +1,4 @@
 import { html } from '../../scripts/scripts.js';
-import '../card-carousel/card-carousel.js';
 
 const FEED_URL = `${window.hlx.codeBasePath}/assets/fallback.xml`;
 // TODO - Fix
@@ -21,32 +20,31 @@ async function getXMLFeed(url) {
 
 async function renderXMLAsCards(url) {
   const xml = sessionStorage.getItem('blog') || (await getXMLFeed(url));
+  if (!xml) return;
+  const parser = new DOMParser();
+  const dom = parser.parseFromString(xml, 'application/xml');
+  const items = dom.getElementsByTagName('item');
+  let cards = '';
+  for (let i = 0; i < items.length; i += 1) {
+    const title = items[i].getElementsByTagName('title');
+    const link = items[i].getElementsByTagName('link');
+    const pubDate = items[i].getElementsByTagName('pubDate');
+    const readTime = items[i].getElementsByTagName('readTime');
+    const featuredImage = items[i].getElementsByTagName('featuredImage');
+    const background = featuredImage[0].textContent;
+    const backgroundStyle = background
+      ? `url(${featuredImage[0].textContent}) center center no-repeat`
+      : 'url(/assets/card-background.jpg) 0 0 no-repeat';
+    const _pubDate = new Date(pubDate?.[0]?.textContent);
+    const pubDateToLocale = _pubDate.toLocaleString('default', {
+      month: 'long',
+      day: 'numeric',
+      year: 'numeric',
+    });
 
-  if (xml) {
-    const parser = new DOMParser();
-    const dom = parser.parseFromString(xml, 'application/xml');
-    const items = dom.getElementsByTagName('item');
-    let cards = '';
-    for (let i = 0; i < items.length; i += 1) {
-      const title = items[i].getElementsByTagName('title');
-      const link = items[i].getElementsByTagName('link');
-      const pubDate = items[i].getElementsByTagName('pubDate');
-      const readTime = items[i].getElementsByTagName('readTime');
-      const featuredImage = items[i].getElementsByTagName('featuredImage');
-      const background = featuredImage[0].textContent;
-      const backgroundStyle = background
-        ? `url(${featuredImage[0].textContent}) center center no-repeat`
-        : 'url(/assets/card-background.jpg) 0 0 no-repeat';
-      const _pubDate = new Date(pubDate?.[0]?.textContent);
-      const pubDateToLocale = _pubDate.toLocaleString('default', {
-        month: 'long',
-        day: 'numeric',
-        year: 'numeric',
-      });
-
-      // NOTE: using divs instead of lists due to an a11y bug in splide
-      // see: https://github.com/Splidejs/splide/issues/1241
-      cards += `\
+    // NOTE: using divs instead of lists due to an a11y bug in splide
+    // see: https://github.com/Splidejs/splide/issues/1241
+    cards += `\
     <div class="splide__slide">
       <a href="${link[0].textContent}" class="card ${
   background && 'has-custom-background'
@@ -59,15 +57,25 @@ async function renderXMLAsCards(url) {
         </h5>
       </a>
     </div>`;
-    }
+  }
 
-    const carouselList = document.querySelector(
-      '.carousel-container .splide__list',
-    );
-    carouselList.innerHTML = cards;
+  const carouselList = document.querySelector(
+    '.carousel-container .splide__list',
+  );
+  carouselList.innerHTML = cards;
 
-    store.emit('blog:loaded');
-  }
+  store.emit('blog:loaded');
+}
+
+function imageAppear(block) {
+  const obs = new IntersectionObserver((entries, self) => {
+    const inView = entries.find((entry) => entry.isIntersecting);
+    if (!inView) return;
+
+    block.classList.add('in-view');
+    self.disconnect();
+  });
+  obs.observe(block);
 }
 
 /**
@@ -80,5 +88,7 @@ export default async function decorate(block) {
     </div>
   `);
 
+  await import('../card-carousel/card-carousel.js');
+  imageAppear(block);
   await renderXMLAsCards(FEED_URL);
 }