diff --git a/creativecloud/blocks/interactive-metadata/interactive-metadata.css b/creativecloud/blocks/interactive-metadata/interactive-metadata.css index f01cb4a94..806979cb8 100644 --- a/creativecloud/blocks/interactive-metadata/interactive-metadata.css +++ b/creativecloud/blocks/interactive-metadata/interactive-metadata.css @@ -17,16 +17,6 @@ margin: 0; } -.interactive-enabled.heading-top h1, -.interactive-enabled.heading-top h2, -.interactive-enabled.heading-top h3, -.interactive-enabled.heading-top h4, -.interactive-enabled.heading-top h5, -.interactive-enabled.heading-top h6, -.interactive-enabled .foreground .image .mobile-top-title { - display: none; -} - .interactive-enabled .foreground.container .image { flex-direction: column; } @@ -269,7 +259,17 @@ width: 100%; } - .interactive-enabled.heading-top .foreground .image .mobile-top-title { + .interactive-enabled.mobile-heading-top h1, + .interactive-enabled.mobile-heading-top h2, + .interactive-enabled.mobile-heading-top h3, + .interactive-enabled.mobile-heading-top h4, + .interactive-enabled.mobile-heading-top h5, + .interactive-enabled.mobile-heading-top h6, + .interactive-enabled .foreground .image .mobile-heading-top { + display: none; + } + + .interactive-enabled.mobile-heading-top .foreground .image .mobile-heading-top { display: block; margin-bottom: 24px; font-size: 36px; @@ -279,13 +279,8 @@ } @media screen and (min-width: 600px) { - .interactive-enabled.heading-top h1, - .interactive-enabled.heading-top h2, - .interactive-enabled.heading-top h3, - .interactive-enabled.heading-top h4, - .interactive-enabled.heading-top h5, - .interactive-enabled.heading-top h6 { - display: block; + .interactive-enabled .foreground .image .mobile-heading-top { + display: none; } .interactive-enabled .foreground.container .image > p:first-child { diff --git a/creativecloud/blocks/interactive-metadata/interactive-metadata.js b/creativecloud/blocks/interactive-metadata/interactive-metadata.js index e6da45089..136097446 100644 --- a/creativecloud/blocks/interactive-metadata/interactive-metadata.js +++ b/creativecloud/blocks/interactive-metadata/interactive-metadata.js @@ -172,7 +172,7 @@ async function implementWorkflow(stepInfo) { function checkRenderStatus(targetBlock, res, rej, etime, rtime) { if (etime > 20000) { rej(); return; } - if (targetBlock.querySelector('.text') && targetBlock.querySelector('.image')) res(); + if (targetBlock.querySelector('.text') && targetBlock.querySelector('.asset, .image')) res(); else setTimeout(() => checkRenderStatus(targetBlock, res, rej, etime + rtime), rtime); } @@ -196,11 +196,11 @@ function decorateEnticementArrow(aa) { } function decorateMobileHeading(intEnb) { - if (!intEnb.classList.contains('heading-top')) return; + if (!intEnb.classList.contains('mobile-heading-top')) return; const h = intEnb.querySelector('.text').querySelector('h1, h2, h3, h4, h5, h6'); if (!h) return; const htxt = h.textContent; - const hTxtTop = createTag('div', { class: 'mobile-top-title' }, htxt); + const hTxtTop = createTag('div', { class: 'mobile-heading-top' }, htxt); intEnb.querySelector('.image').prepend(hTxtTop); } @@ -256,6 +256,9 @@ function getWorkFlowInformation(el) { 'workflow-generate-crop': ['generate', 'selector-tray', 'crop', 'start-over'], 'workflow-generate-repeat-crop': ['generate', 'selector-tray', 'generate', 'selector-tray', 'crop', 'start-over'], 'workflow-hue-sat': ['slider-tray'], + 'workflow-generate-select-generate': ['generate', 'selector-tray', 'generate', 'crop', 'start-over'], + 'workflow-generate-selector': ['generate', 'selector-tray', 'generate', 'start-over'], + 'workflow-generate-triple-selector': ['generate', 'selector-tray', 'generate', 'selector-tray', 'generate', 'selector-tray', 'start-over'], }; const wfNames = Object.keys(intWorkFlowConfig); [...el.classList].forEach((cn) => { if (cn.match('workflow-')) wfName = cn; }); diff --git a/creativecloud/features/interactive-components/crop/crop.js b/creativecloud/features/interactive-components/crop/crop.js index 50aa1b2da..0675a800f 100644 --- a/creativecloud/features/interactive-components/crop/crop.js +++ b/creativecloud/features/interactive-components/crop/crop.js @@ -6,11 +6,13 @@ export default async function stepInit(data) { const layer = createTag('div', { class: `layer layer-${data.stepIndex}` }); const cropCTA = createTag('a', { class: 'gray-button body-m crop-button', href: '#' }); const svg = config.querySelector('img[src*=".svg"')?.closest('picture'); + const lastp = config.querySelector(':scope > div > p:last-child'); + const textContent = lastp.textContent.trim(); if (svg) { svg.insertAdjacentElement('afterend', svg.cloneNode(true)); cropCTA.appendChild(createTag('div', { class: 'crop-icon-container' }, svg)); } - if (config.textContent) cropCTA.appendChild(document.createTextNode(config.textContent.trim())); + if (textContent) cropCTA.appendChild(document.createTextNode(textContent)); cropCTA.addEventListener('click', async (e) => { e.preventDefault(); await data.openForExecution; diff --git a/creativecloud/features/interactive-components/generate/generate.css b/creativecloud/features/interactive-components/generate/generate.css index 1409406d5..64bb14465 100644 --- a/creativecloud/features/interactive-components/generate/generate.css +++ b/creativecloud/features/interactive-components/generate/generate.css @@ -84,15 +84,15 @@ padding: 0; } - .interactive-enabled.generate-right .step-generate .generate-prompt-button, - .interactive-enabled .step-generate .generate-right .generate-prompt-button { + .interactive-enabled.generate-side .step-generate .generate-prompt-button, + .interactive-enabled .step-generate .generate-side .generate-prompt-button { left: auto; right: -21.5%; bottom: calc(50% - 80px); } - [dir="rtl"] .interactive-enabled.generate-right .step-generate .generate-prompt-button, - [dir="rtl"] .interactive-enabled .step-generate .generate-right .generate-prompt-button { + [dir="rtl"] .interactive-enabled.generate-side .step-generate .generate-prompt-button, + [dir="rtl"] .interactive-enabled .step-generate .generate-side .generate-prompt-button { left: auto; right: -21.5%; } @@ -131,21 +131,21 @@ max-width: 218px; } - .interactive-enabled.row-reversed.generate-right .step-generate .generate-prompt-button, - .interactive-enabled.row-reversed .step-generate .generate-right .generate-prompt-button { + .interactive-enabled.row-reversed.generate-side .step-generate .generate-prompt-button, + .interactive-enabled.row-reversed .step-generate .generate-side .generate-prompt-button { flex-direction: row; left: -21.5%; right: auto; } - [dir="rtl"] .interactive-enabled.generate-right .step-generate .generate-prompt-button, - [dir="rtl"] .interactive-enabled .step-generate .generate-right .generate-prompt-button { + [dir="rtl"] .interactive-enabled.generate-side .step-generate .generate-prompt-button, + [dir="rtl"] .interactive-enabled .step-generate .generate-side .generate-prompt-button { left: -21.5%; right: auto; } - [dir="rtl"] .interactive-enabled.row-reversed.generate-right .step-generate .generate-prompt-button, - [dir="rtl"] .interactive-enabled.row-reversed .step-generate .generate-right .generate-prompt-button { + [dir="rtl"] .interactive-enabled.row-reversed.generate-side .step-generate .generate-prompt-button, + [dir="rtl"] .interactive-enabled.row-reversed .step-generate .generate-side .generate-prompt-button { left: auto; right: -21.5%; } diff --git a/creativecloud/features/interactive-components/generate/generate.js b/creativecloud/features/interactive-components/generate/generate.js index 0e11aeeef..3421b287b 100644 --- a/creativecloud/features/interactive-components/generate/generate.js +++ b/creativecloud/features/interactive-components/generate/generate.js @@ -4,8 +4,8 @@ export default async function stepInit(data) { data.target.classList.add('step-generate'); const config = data.stepConfigs[data.stepIndex]; const layer = createTag('div', { class: `layer layer-${data.stepIndex}` }); - const [searchText, btnText, position] = config.textContent.trim().split('|'); - if (position) layer.classList.add(`generate-${position.toLowerCase().trim()}`); + const lastp = config.querySelector(':scope > div > p:last-child'); + const [searchText, btnText] = lastp.textContent.trim().split('|'); const genfillDiv = createTag('div', { class: 'generate-prompt-button body-m' }); const searchBar = createTag('div', { class: 'generate-text' }, `${searchText}`); const searchBarContainer = createTag('div', { class: 'generate-text-container' }, searchBar); diff --git a/creativecloud/features/interactive-components/selector-tray/selector-tray.js b/creativecloud/features/interactive-components/selector-tray/selector-tray.js index c138d524a..2648e844d 100644 --- a/creativecloud/features/interactive-components/selector-tray/selector-tray.js +++ b/creativecloud/features/interactive-components/selector-tray/selector-tray.js @@ -3,17 +3,17 @@ import { handleImageTransition, getImgSrc } from '../../../blocks/interactive-me function getTrayConfig(data) { const dpth = data.displayPath; - const allUls = data.stepConfigs[data.stepIndex].querySelectorAll('ul'); - const configUl = (dpth >= 0 && allUls.length > dpth) ? allUls[dpth] : allUls[0]; - return configUl; + const allTrays = data.stepConfigs[data.stepIndex].querySelectorAll('ul, ol'); + const configTray = (dpth >= 0 && allTrays.length > dpth) ? allTrays[dpth] : allTrays[0]; + return configTray; } function getStartingPathIdx(data) { let pathIdx = 0; const dpth = data.displayPath; - const allUls = data.stepConfigs[data.stepIndex].querySelectorAll('ul'); - if (allUls.length < dpth) return pathIdx; - for (let i = 0; i < dpth; i += 1) pathIdx += allUls[i].querySelectorAll('li').length; + const allTrays = data.stepConfigs[data.stepIndex].querySelectorAll('ul, ol'); + if (allTrays.length < dpth) return pathIdx; + for (let i = 0; i < dpth; i += 1) pathIdx += allTrays[i].querySelectorAll('li').length; return pathIdx; } @@ -47,23 +47,20 @@ function attachThumbnailEvents(a, data, layer) { const trObj = { src: curra.dataset.dispSrc, alt: curra.dataset.dispAlt, useCfg: true }; await handleImageTransition(data, trObj); data.el.dispatchEvent(new CustomEvent(data.nextStepEvent)); - e.target.closest('.tray-items').querySelector('a.tray-thumbnail-img').classList.add('thumbnail-selected'); }); } function selectorTrayWithImgs(layer, data) { const selectorTray = createTag('div', { class: 'body-s selector-tray' }); const trayItems = createTag('div', { class: 'tray-items' }); - const configUl = getTrayConfig(data); - const pics = configUl.querySelectorAll('picture'); + const configTray = getTrayConfig(data); + const options = configTray.querySelectorAll('li'); let pathIdx = getStartingPathIdx(data); let displayImg = null; - [...pics].forEach((pic, idx) => { - if (idx % 2 === 0) { - displayImg = [getImgSrc(pic), pic.querySelector('img').alt]; - return; - } - const a = createSelectorThumbnail(pic, pathIdx, displayImg); + [...options].forEach((o) => { + const [thumbnailPic, displayPic] = o.querySelectorAll('picture'); + displayImg = [getImgSrc(displayPic), displayPic.querySelector('img').alt]; + const a = createSelectorThumbnail(thumbnailPic, pathIdx, displayImg); trayItems.append(a); pathIdx += 1; attachThumbnailEvents(a, data, layer); @@ -79,10 +76,7 @@ export default async function stepInit(data) { const title = config.querySelector('p:first-child'); let trayTitle = null; if (title) trayTitle = createTag('div', { class: 'tray-title' }, title.innerText.trim()); - const trayConfig = config.querySelectorAll('ul > li'); - const isGenerateTray = [...trayConfig].filter((li) => (li.querySelector('img[src*="media_"]').length >= 2)); - let selectorTray = null; - if (isGenerateTray) selectorTray = selectorTrayWithImgs(layer, data); + const selectorTray = selectorTrayWithImgs(layer, data); if (title) selectorTray.prepend(trayTitle); layer.append(selectorTray); return layer; diff --git a/creativecloud/features/interactive-components/slider-tray/slider-tray.js b/creativecloud/features/interactive-components/slider-tray/slider-tray.js index 57769363b..cbb1e8ec1 100644 --- a/creativecloud/features/interactive-components/slider-tray/slider-tray.js +++ b/creativecloud/features/interactive-components/slider-tray/slider-tray.js @@ -15,7 +15,7 @@ async function createSelectorTray(data, layer) { const sliderTray = createTag('div', { class: 'sliderTray' }); const menu = createTag('div', { class: 'menu' }); const config = data.stepConfigs[data.stepIndex]; - const options = config.querySelectorAll(':scope > div .icon'); + const options = config.querySelectorAll(':scope > div ul .icon, :scope > div ol .icon'); [...options].forEach((o) => { handleInput(o, sliderTray, menu, layer); }); layer.append(sliderTray); observeSliderTray(sliderTray, data.target, menu); diff --git a/creativecloud/features/interactive-components/start-over/start-over.css b/creativecloud/features/interactive-components/start-over/start-over.css index 21e03c97e..ee87bb970 100644 --- a/creativecloud/features/interactive-components/start-over/start-over.css +++ b/creativecloud/features/interactive-components/start-over/start-over.css @@ -14,7 +14,7 @@ gap: 16px; } - .interactive-enabled.generate-right .step-start-over .layer .gray-button.start-over-button { + .interactive-enabled.generate-side .step-start-over .layer .gray-button.start-over-button { bottom: 32px; } } diff --git a/test/blocks/interactive-metadata/interactive-metadata.test.js b/test/blocks/interactive-metadata/interactive-metadata.test.js index c281e889f..b64fdcca8 100644 --- a/test/blocks/interactive-metadata/interactive-metadata.test.js +++ b/test/blocks/interactive-metadata/interactive-metadata.test.js @@ -1,32 +1,37 @@ import { readFile } from '@web/test-runner-commands'; import { expect } from '@esm-bundle/chai'; -document.body.innerHTML = await readFile({ path: './mocks/interactive-metadata.html' }); const { setLibs } = await import('../../../creativecloud/scripts/utils.js'); const { default: init } = await import('../../../creativecloud/blocks/interactive-metadata/interactive-metadata.js'); +const { handleImageTransition } = await import('../../../creativecloud/blocks/interactive-metadata/interactive-metadata.js'); +function delay(ms) { + return new Promise((res) => { setTimeout(() => { res(); }, ms); }); +} +document.body.innerHTML = await readFile({ path: './mocks/interactive-metadata.html' }); describe('interactive metadata', () => { let im = null; let ib = null; - let genfillIm = null; - let genfillMarquee = null; before(async () => { setLibs('https://milo.adobe.com/libs'); im = document.querySelector('.interactive-metadata'); ib = document.querySelector('.marquee'); - genfillIm = document.querySelector('.interactive-metadata.workflow-genfill'); - genfillMarquee = genfillIm.closest('.section').querySelector('.marquee'); await init(im); - await init(genfillIm); - }); - it('interactive metadata should exist', () => { - expect(im).to.exist; }); + it('should make the previous block interactive-enabled', () => { expect(ib).to.exist; expect(ib.classList.contains('interactive-enabled')).to.be.true; }); + + it('should start animation', async () => { + const { x, y } = ib.querySelector('.gray-button').getBoundingClientRect(); + window.scrollTo(x, y); + await delay(200); + expect(ib.querySelector('.interactive-holder .show-layer .gray-button.animated')).to.exist; + }); + it('should create a workflow', () => { let hasWorkflowClass = false; im.classList.forEach((className) => { @@ -36,37 +41,32 @@ describe('interactive metadata', () => { }); expect(hasWorkflowClass).to.be.true; }); - it('should render next selector tray', async () => { - im.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); - expect(ib.querySelector('.interactive-holder.step-selector-tray')).to.exist; - }); - it('should render next crop layer', async () => { + + it('should render next layer', async () => { im.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); - expect(ib.querySelector('.interactive-holder.step-crop')).to.exist; + await delay(200); + expect(ib.querySelector('.interactive-holder .layer-1.show-layer')).to.exist; }); - it('should render next start-over layer', async () => { + + it('should render start over layer', async () => { im.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); + await delay(200); expect(ib.querySelector('.interactive-holder.step-start-over')).to.exist; }); - it('should render next generate layer', async () => { - im.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); - expect(ib.querySelector('.interactive-holder.step-generate')).to.exist; - }); - it('Genfill: should render generate layer', () => { - expect(genfillMarquee.querySelector('.interactive-holder.step-generate')).to.exist; - }); - it('Genfill: should render generate layer', async () => { - genfillIm.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); - expect(genfillMarquee.querySelector('.interactive-holder.step-generate')).to.exist; - }); - it('Genfill: should render start over layer', async () => { - genfillIm.dispatchEvent(new CustomEvent('cc:interactive-switch')); - await new Promise((res) => { setTimeout(() => { res(); }, 200); }); - expect(genfillMarquee.querySelector('.interactive-holder.step-start-over')).to.exist; + + it('Transition video', async () => { + const trgt = ib.querySelector('.image .interactive-holder'); + const mockStepInfo = { + im, + stepIndex: 0, + stepName: 'generate', + stepList: ['generate', 'generate', 'start-over'], + stepConfigs: im.querySelectorAll(':scope > div'), + target: trgt, + displayPath: 0, + openForExecution: Promise.resolve(true), + }; + const transitionCfg = { useCfg: true, vsrc: `${window.origin}/videoo.mp4#_autoplay` }; + await handleImageTransition(mockStepInfo, transitionCfg); }); }); diff --git a/test/blocks/interactive-metadata/mocks/interactive-metadata.html b/test/blocks/interactive-metadata/mocks/interactive-metadata.html index e08c13b9d..038a34eac 100644 --- a/test/blocks/interactive-metadata/mocks/interactive-metadata.html +++ b/test/blocks/interactive-metadata/mocks/interactive-metadata.html @@ -1,150 +1,5 @@
-
-
-
-

Everyone can. Photoshop.

-

Dream it, type it, and see it with generative AI features in Photoshop. Add or extend content - in any image to turn portraits into standout headshots and more.

-

Free Trial Try Generative Fill

-
-
-

- See it - in action -

-

- - - - - - -

-
-
-
-
-
-
-

- -

-

Beautiful full moon | Generate

-
-
-
-
-

Select a variation

-

- - - - - - -

-
    -
  • - - - - - - - - - - - - -
  • -
  • - - - - - - - - - - - - -
  • -
  • - - - - - - - - - - - - -
  • -
-
-
-
-
-

- -

-

Crop

-
-
-
-
-

https://main--cc--adobecom.hlx.page/drafts/mathuria/interactiveelems/demo/northernlights/assets/moon1-video.mp4#_autoplay -

-

https://main--cc--adobecom.hlx.page/drafts/mathuria/interactiveelems/demo/northernlights/assets/moon2-video.mp4#_autoplay -

-

https://main--cc--adobecom.hlx.page/drafts/mathuria/interactiveelems/demo/northernlights/assets/moon3-video.mp4#_autoplay -

-

- -

-

Start Over | 1000

-
-
-
-
-
-
diff --git a/test/features/interactive-components/crop/mocks/body.html b/test/features/interactive-components/crop/mocks/body.html index 2ee974338..1f5807e71 100644 --- a/test/features/interactive-components/crop/mocks/body.html +++ b/test/features/interactive-components/crop/mocks/body.html @@ -1,5 +1,5 @@
-
diff --git a/test/features/interactive-components/generate/mocks/body.html b/test/features/interactive-components/generate/mocks/body.html index fc22e186a..9873daf20 100644 --- a/test/features/interactive-components/generate/mocks/body.html +++ b/test/features/interactive-components/generate/mocks/body.html @@ -1,5 +1,5 @@
-
+
diff --git a/test/features/interactive-components/selector-tray/mocks/body.html b/test/features/interactive-components/selector-tray/mocks/body.html index 5a2341507..813b29aee 100644 --- a/test/features/interactive-components/selector-tray/mocks/body.html +++ b/test/features/interactive-components/selector-tray/mocks/body.html @@ -1,5 +1,5 @@
-
diff --git a/test/features/interactive-components/start-over/mocks/body.html b/test/features/interactive-components/start-over/mocks/body.html index da64587d2..4f301305b 100644 --- a/test/features/interactive-components/start-over/mocks/body.html +++ b/test/features/interactive-components/start-over/mocks/body.html @@ -1,5 +1,5 @@
-
+

Everyone can. Photoshop.