Skip to content

Commit

Permalink
Merge pull request #144 from drashti1712/genfill-flicker
Browse files Browse the repository at this point in the history
[MWPW-140096] Genfill Marquee images are blinking during auto play and on click as well in Firefox browser
  • Loading branch information
drashti1712 authored Dec 14, 2023
2 parents ad3c16c + 2617356 commit 225a647
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default async function init(el) {
loadStyle('/creativecloud/features/genfill/genfill-interactive.css');
interactiveInit(el, decorateButtons, decorateBlockBg, createTag);
const { default: decorateGenfill } = await import('../../features/genfill/genfill-interactive.js');
await decorateGenfill(el);
await decorateGenfill(el, { createTag });
break;
}
case el.classList.contains('firefly'): {
Expand Down
29 changes: 7 additions & 22 deletions creativecloud/features/genfill/genfill-interactive.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.genfill .tablet-only,
.genfill .mobile-only {
-webkit-tap-highlight-color: transparent;
-webkit-user-select: none;
user-select: none;
display: none;
}
Expand All @@ -12,11 +13,10 @@
}

.genfill .media a {
display: none;
}

.interactive-marquee.genfill .media a {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
}

.enticement-arrow {
Expand All @@ -42,12 +42,7 @@
}

@media screen and (max-width: 600px) {
.genfill .mobile-only a {
display: none;
}

.genfill .media.mobile-only,
.genfill .media.mobile-only a:first-of-type {
.genfill .mobile-only {
display: block;
}

Expand All @@ -57,12 +52,7 @@
}

@media screen and (min-width: 600px) and (max-width: 1200px) {
.genfill .tablet-only a {
display: none;
}

.genfill .tablet-only,
.genfill .tablet-only a:first-of-type {
.genfill .tablet-only {
display: block;
}

Expand All @@ -83,12 +73,7 @@
}

@media screen and (min-width: 1200px) {
.genfill .desktop-only a {
display: none;
}

.genfill .desktop-only,
.genfill .desktop-only a:first-of-type {
.genfill .desktop-only {
display: block;
}

Expand Down
160 changes: 91 additions & 69 deletions creativecloud/features/genfill/genfill-interactive.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,90 @@
import { getLibs } from '../../scripts/utils.js';
import { createEnticement } from '../interactive-elements/interactive-elements.js';
import defineDeviceByScreenSize from '../../scripts/decorate.js';

function handleTransition(pics, index) {
pics[index].style.display = 'none';
const nextIndex = (index + 1) % pics.length;
pics[nextIndex].style.display = 'block';
async function addEnticement(container, enticement, mode) {
const svgUrl = enticement.querySelector('a').href;
const enticementText = enticement.innerText;
const entcmtEl = await createEnticement(`${enticementText}|${svgUrl}`, mode);
entcmtEl.classList.add('enticement');
const viewports = ['tablet', 'desktop'];
viewports.forEach((v) => {
const mDiv = container.querySelector(`.media.${v}-only`);
mDiv.insertBefore(entcmtEl.cloneNode(true), mDiv.firstElementChild);
});
}

function generateDaaLL(hText, alt, v) {
const altTxt = alt
? `${alt}|Marquee|${hText}`
: `Image-${v}|Marquee|${hText}`;
return altTxt;
}

function setImgAttrs(img, src, attrs) {
img.src = src;
if (attrs.alt) img.alt = attrs.alt;
if (attrs.w) img.width = attrs.w;
if (attrs.h) img.height = attrs.h;
}

function handleClick(a, v, deviceConfig, hText) {
const img = a.querySelector('img');
const currIndex = deviceConfig[v].index;
const nextIndex = (currIndex + 1) % deviceConfig[v].srcList.length;
const src = deviceConfig[v].srcList[nextIndex];
const attrs = deviceConfig[v].attrList[nextIndex];
setImgAttrs(img, src, attrs);
a.setAttribute('daa-ll', generateDaaLL(hText, attrs.alt, v));
deviceConfig[v].index = nextIndex;
return nextIndex;
}

function startAutocycle(interval, pics, clickConfig) {
if (clickConfig.isImageClicked) return;
clickConfig.autocycleInterval = setInterval(() => {
clickConfig.autocycleIndex = handleTransition(pics, clickConfig.autocycleIndex);
if (clickConfig.autocycleIndex === pics.length - 1) {
clearInterval(clickConfig.autocycleInterval);
function startAutocycle(a, autoCycleConfig, viewport, deviceConfig, interval, hText) {
if (autoCycleConfig.isImageClicked) return;
autoCycleConfig.autocycleInterval = setInterval(() => {
handleClick(a, viewport, deviceConfig, hText);
if (autoCycleConfig.isImageClicked
|| deviceConfig[viewport].index === deviceConfig[viewport].srcList.length - 1) {
clearInterval(autoCycleConfig.autocycleInterval);
}
}, interval);
}

function handleClick(aTags, clickConfig) {
aTags.forEach((a, i) => {
a.querySelector('img').removeAttribute('loading');
a.addEventListener('click', () => {
clickConfig.isImageClicked = true;
if (clickConfig.autocycleInterval) clearInterval(clickConfig.autocycleInterval);
handleTransition(aTags, i);
});
function processMedia(ic, miloUtil, autoCycleConfig, deviceConfig, v, hText) {
const media = miloUtil.createTag('div', { class: `media ${v}-only` });
const a = miloUtil.createTag('a', { class: 'genfill-link' });
const img = miloUtil.createTag('img', { class: 'genfill-image' });
const src = deviceConfig[v].srcList[0];
const attrs = deviceConfig[v].attrList[0];
setImgAttrs(img, src, attrs);
a.setAttribute('daa-ll', generateDaaLL(hText, attrs.alt, v));
a.appendChild(img);
media.appendChild(a);
ic.appendChild(media);
a.addEventListener('click', () => {
autoCycleConfig.isImageClicked = true;
if (autoCycleConfig.autocycleInterval) clearInterval(autoCycleConfig.autocycleInterval);
handleClick(a, v, deviceConfig, hText);
});
}

async function addEnticement(container, enticement, mode) {
const svgUrl = enticement.querySelector('a').href;
const enticementText = enticement.innerText;
const entcmtEl = await createEnticement(`${enticementText}|${svgUrl}`, mode);
entcmtEl.classList.add('enticement');
const n = container.children.length;
const desktopMedia = container.querySelector('.desktop-only');
const tabletMedia = (n > 2) ? container.querySelector('.tablet-only') : null;
desktopMedia.insertBefore(entcmtEl, desktopMedia.firstElementChild);
tabletMedia?.insertBefore(entcmtEl.cloneNode(true), tabletMedia.firstElementChild);
}

async function removePTags(media, vi) {
const heading = media.closest('.foreground').querySelector('h1, h2, h3, h4, h5, h6');
const hText = heading.id
.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');
const miloLibs = getLibs();
const { createTag } = await import(`${miloLibs}/utils/utils.js`);
const pics = media.querySelectorAll('picture');
pics.forEach((pic, index) => {
if (pic.closest('p')) pic.closest('p').remove();
const a = createTag('a', { class: 'genfill-link' });
const img = pic.querySelector('img');
const altTxt = img.alt
? `${img.alt}|Marquee|${hText}`
: `Image-${vi}-${index}|Marquee|${hText}`;
a.setAttribute('daa-ll', altTxt);
a.appendChild(pic);
media.appendChild(a);
});
function getImgSrc(pic, viewport) {
let source = '';
if (viewport === 'mobile') source = pic.querySelector('source[type="image/webp"]:not([media])');
else source = pic.querySelector('source[type="image/webp"][media]');
return source.srcset;
}

export default async function decorateGenfill(el) {
const clickConfig = {
autocycleIndex: 0,
export default async function decorateGenfill(el, miloUtil) {
const autoCycleConfig = {
autocycleInterval: null,
isImageClicked: false,
};
const interactiveContainer = el.querySelector('.interactive-container');
const allP = interactiveContainer.querySelectorAll('.media:first-child p');
const ic = el.querySelector('.interactive-container');
const heading = ic.closest('.foreground').querySelector('h1, h2, h3, h4, h5, h6');
const hText = heading.id
.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');
const allP = ic.querySelectorAll('.media:first-child p');
const pMetadata = [...allP].filter((p) => !p.querySelector('picture'));
const [enticement, timer = null] = [...pMetadata];
enticement.classList.add('enticement-detail');
Expand All @@ -79,24 +94,31 @@ export default async function decorateGenfill(el) {
const [intervalTime = 2000, delayTime = 1000] = (timerValues && timerValues.length > 1)
? timerValues : [2000];
[enticement, timer].forEach((i) => i?.remove());
const currentDom = ic.cloneNode(true);
ic.innerHTML = '';
const viewports = ['mobile', 'tablet', 'desktop'];
const mediaElements = interactiveContainer.querySelectorAll('.media');
mediaElements.forEach(async (mediaEl, index) => {
await removePTags(mediaEl, index);
const aTags = mediaEl.querySelectorAll('a');
handleClick(aTags, clickConfig);
});
const deviceConfig = {
mobile: { srcList: [], attrList: [], index: 0 },
tablet: { srcList: [], attrList: [], index: 0 },
desktop: { srcList: [], attrList: [], index: 0 },
};
const mediaElements = currentDom.querySelectorAll('.media');
viewports.forEach((v, vi) => {
const media = mediaElements[vi]
? mediaElements[vi]
: interactiveContainer.lastElementChild;
media.classList.add(`${v}-only`);
if (defineDeviceByScreenSize() === v.toUpperCase()) {
setTimeout(() => {
const aTags = media.querySelectorAll('a');
startAutocycle(intervalTime, aTags, clickConfig);
}, delayTime);
}
: currentDom.lastElementChild;
[...media.querySelectorAll('picture')].forEach((pic, index) => {
const src = getImgSrc(pic, v);
deviceConfig[v].srcList.push(src);
const img = pic.querySelector('img');
deviceConfig[v].attrList.push({ alt: img.alt, w: img.width, h: img.height });
if (index === 0) processMedia(ic, miloUtil, autoCycleConfig, deviceConfig, v, hText);
});
});
addEnticement(interactiveContainer, enticement, mode);
const currentVP = defineDeviceByScreenSize().toLocaleLowerCase();
setTimeout(() => {
const aTag = ic.querySelector(`.${currentVP}-only a`);
startAutocycle(aTag, autoCycleConfig, currentVP, deviceConfig, intervalTime, hText);
}, delayTime);
addEnticement(ic, enticement, mode);
}
6 changes: 6 additions & 0 deletions test/features/genfill/genfill-interactive.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ describe('genfill variant of interactive marquee', () => {
expect(ent.querySelector('.enticement-text')).to.exist;
expect(ent.querySelector('.enticement-arrow')).to.exist;
});
it('should implement click functionality and analytics', () => {
const a = im.querySelector('.desktop-only a');
expect(a.getAttribute('daa-ll').includes('Generate Jungle')).to.true;
a.click();
expect(a.getAttribute('daa-ll').includes('Generate Pond')).to.true;
});
});
74 changes: 21 additions & 53 deletions test/features/genfill/mocks/genfill.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<div class="interactive-marquee light genfill">
<div class="interactive-marquee genfill">
<div>
<div data-valign="middle">
<picture>
<source type="image/webp" srcset="" media="(min-width: 600px)">
<source type="image/webp" srcset="">
<source type="image/png" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="" src="" width="1600" height="750">
</picture>
</div>
Expand All @@ -10,76 +13,41 @@
<div data-valign="middle">
<p>
<picture>
<img loading="lazy" alt="" src="" width="154" height="150">
<source type="image/webp" srcset="" media="(min-width: 600px)">
<source type="image/webp" srcset="">
<source type="image/png" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="" src="" width="154" height="150">
</picture>Photoshop
</p>
<h2 id="edit-photos-online-with-adobe-photoshop">Edit photos online with Adobe Photoshop</h2>
<p>Add, remove, or expand content in images right in your browser with Photoshop on the web. Included in every Photoshop plan.</p>
<p><strong><a href="https://www.adobe.com/">Free Trial</a></strong> <em><a href="http://www.adobe.com/">Explore Photoshop online</a></em></p>
</div>
<div data-valign="middle">
<p><a href="/drafts/ruchika/svg/enticement-arrow.svg">See it in action</a></p>
<p><a href="">See it in action</a></p>
<p>2000|0</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="" media="(min-width: 600px)">
<source type="image/webp" srcset="">
<source type="image/jpeg" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="Generate Jungle" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="" media="(min-width: 600px)">
<source type="image/webp" srcset="">
<source type="image/jpeg" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="Generate Pond" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
</div>
<div data-valign="middle">
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="" media="(min-width: 600px)">
<source type="image/webp" srcset="">
<source type="image/jpeg" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="Generate Jaguar" src="" width="1000" height="1000">
</picture>
</p>
</div>
Expand Down

0 comments on commit 225a647

Please sign in to comment.