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

[MWPW-140096] Genfill Marquee images are blinking during auto play and on click as well in Firefox browser #144

Merged
merged 18 commits into from
Dec 14, 2023
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
146 changes: 77 additions & 69 deletions creativecloud/features/genfill/genfill-interactive.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,74 @@
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(`.${v}-only`);
mDiv.insertBefore(entcmtEl.cloneNode(true), mDiv.firstElementChild);
aishwaryamathuria marked this conversation as resolved.
Show resolved Hide resolved
});
}

function handleClick(a, viewport, deviceConfig) {
const img = a.querySelector('img');
const currIndex = deviceConfig[viewport].index;
const nextIndex = (currIndex + 1) % deviceConfig[viewport].srcList.length;
img.src = deviceConfig[viewport].srcList[nextIndex];
img.alt = deviceConfig[viewport].altList[nextIndex];
a.setAttribute('daa-ll', img.alt);
aishwaryamathuria marked this conversation as resolved.
Show resolved Hide resolved
deviceConfig[viewport].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) {
if (autoCycleConfig.isImageClicked) return;
autoCycleConfig.autocycleInterval = setInterval(() => {
handleClick(a, viewport, deviceConfig);
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, viewport) {
const media = miloUtil.createTag('div', { class: `media ${viewport}-only` });
const a = miloUtil.createTag('a', { class: 'genfill-link' });
const img = miloUtil.createTag('img', { class: 'genfill-image' });
[img.alt] = [deviceConfig[viewport].altList];
[img.src] = [deviceConfig[viewport].srcList];
aishwaryamathuria marked this conversation as resolved.
Show resolved Hide resolved
a.setAttribute('daa-ll', img.alt);
a.appendChild(img);
media.appendChild(a);
ic.appendChild(media);
a.addEventListener('click', () => {
autoCycleConfig.isImageClicked = true;
if (autoCycleConfig.autocycleInterval) clearInterval(autoCycleConfig.autocycleInterval);
handleClick(a, viewport, deviceConfig);
});
}

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 +78,33 @@ 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: [], altList: [], index: 0 },
tablet: { srcList: [], altList: [], index: 0 },
desktop: { srcList: [], altList: [], 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 altTxt = pic.querySelector('img').alt
? `${pic.querySelector('img').alt}|Marquee|${hText}`
aishwaryamathuria marked this conversation as resolved.
Show resolved Hide resolved
: `Image-${v}-${index}|Marquee|${hText}`;
deviceConfig[v].altList.push(altTxt);
if (index === 0) processMedia(ic, miloUtil, autoCycleConfig, deviceConfig, v);
});
});
addEnticement(interactiveContainer, enticement, mode);
const currentVP = defineDeviceByScreenSize().toLocaleLowerCase();
setTimeout(() => {
const aTag = ic.querySelector(`.${currentVP}-only a`);
startAutocycle(aTag, autoCycleConfig, currentVP, deviceConfig, intervalTime);
}, delayTime);
addEnticement(ic, enticement, mode);
}
7 changes: 7 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,11 @@ 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', () => {
const a = im.querySelector('.desktop-only a');
const img = a.querySelector('img');
expect(img.alt.includes('Generate Jungle')).to.true;
a.click();
expect(img.alt.includes('Generate Pond')).to.true;
});
});
74 changes: 37 additions & 37 deletions test/features/genfill/mocks/genfill.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
<div class="interactive-marquee light genfill">
<div class="interactive-marquee genfill">
<div>
<div data-valign="middle">
<picture>
<img loading="lazy" alt="" src="" width="1600" height="750">
<source type="image/webp" srcset="./media_17d766f825a9e81814caa27c230d9acc7f824bd7c.png?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_17d766f825a9e81814caa27c230d9acc7f824bd7c.png?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/png" srcset="./media_17d766f825a9e81814caa27c230d9acc7f824bd7c.png?width=2000&amp;format=png&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="" src="./media_17d766f825a9e81814caa27c230d9acc7f824bd7c.png?width=750&amp;format=png&amp;optimize=medium" width="1600" height="750">
</picture>
</div>
</div>
<div>
<div data-valign="middle">
<p>
<picture>
<img loading="lazy" alt="" src="" width="154" height="150">
<source type="image/webp" srcset="./media_12bfb726aa0bd8e9f444f69e2bbeb3950cb2a867b.png?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_12bfb726aa0bd8e9f444f69e2bbeb3950cb2a867b.png?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/png" srcset="./media_12bfb726aa0bd8e9f444f69e2bbeb3950cb2a867b.png?width=2000&amp;format=png&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="" src="./media_12bfb726aa0bd8e9f444f69e2bbeb3950cb2a867b.png?width=750&amp;format=png&amp;optimize=medium" width="154" height="150">
</picture>Photoshop
</p>
<h2 id="edit-photos-online-with-adobe-photoshop">Edit photos online with Adobe Photoshop</h2>
Expand All @@ -22,64 +28,58 @@ <h2 id="edit-photos-online-with-adobe-photoshop">Edit photos online with Adobe P
<p>2000|0</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_199aaddd744e212cd4a521e7f1ea658e219e415a9.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_199aaddd744e212cd4a521e7f1ea658e219e415a9.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_199aaddd744e212cd4a521e7f1ea658e219e415a9.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Generate Jungle" src="./media_199aaddd744e212cd4a521e7f1ea658e219e415a9.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_126c171cba648be0cf4bfb103f2b1a0c57f057d9c.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_126c171cba648be0cf4bfb103f2b1a0c57f057d9c.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_126c171cba648be0cf4bfb103f2b1a0c57f057d9c.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Generate Pond" src="./media_126c171cba648be0cf4bfb103f2b1a0c57f057d9c.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_1b4b96b28a0346dd1fca00c0e2d9b51cdee362919.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_1b4b96b28a0346dd1fca00c0e2d9b51cdee362919.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_1b4b96b28a0346dd1fca00c0e2d9b51cdee362919.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Jaguar" data-title="JaguarD" src="./media_1b4b96b28a0346dd1fca00c0e2d9b51cdee362919.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_19b938924488c65dc3497a1f78001c221a306faad.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_19b938924488c65dc3497a1f78001c221a306faad.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_19b938924488c65dc3497a1f78001c221a306faad.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Rainforest Plant" data-title="Rainforest PlantD" src="./media_19b938924488c65dc3497a1f78001c221a306faad.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_165ecaae93155e114857d2f6cc24aab7025421d3d.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_165ecaae93155e114857d2f6cc24aab7025421d3d.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_165ecaae93155e114857d2f6cc24aab7025421d3d.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Toucan" data-title="ToucanD" src="./media_165ecaae93155e114857d2f6cc24aab7025421d3d.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
<p>
<picture>
<img loading="lazy" alt="" src="" width="1000" height="1000">
<source type="image/webp" srcset="./media_188299e41c9c7daab1bdb967bf894d49ab73ddf81.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_188299e41c9c7daab1bdb967bf894d49ab73ddf81.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_188299e41c9c7daab1bdb967bf894d49ab73ddf81.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Butterfly" data-title="ButterflyD" src="./media_188299e41c9c7daab1bdb967bf894d49ab73ddf81.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" 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_1e22eda84c1f0358ce15540c9d8cf91bfd8a94578.jpeg?width=2000&amp;format=webply&amp;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_1e22eda84c1f0358ce15540c9d8cf91bfd8a94578.jpeg?width=750&amp;format=webply&amp;optimize=medium">
<source type="image/jpeg" srcset="./media_1e22eda84c1f0358ce15540c9d8cf91bfd8a94578.jpeg?width=2000&amp;format=jpeg&amp;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="Over" data-title="OverD" src="./media_1e22eda84c1f0358ce15540c9d8cf91bfd8a94578.jpeg?width=750&amp;format=jpeg&amp;optimize=medium" width="1000" height="1000">
</picture>
</p>
</div>
Expand Down
Loading