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

[Release] Stage to Main #2742

Merged
merged 8 commits into from
Aug 19, 2024
35 changes: 8 additions & 27 deletions libs/blocks/adobetv/adobetv.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { createIntersectionObserver } from '../../utils/utils.js';
import { applyHoverPlay, getVideoAttrs } from '../../utils/decorate.js';
import { turnAnchorIntoVideo } from '../../utils/decorate.js';

const ROOT_MARGIN = 1000;

const loadAdobeTv = (a) => {
export default function init(a) {
a.classList.add('hide-video');
const bgBlocks = ['aside', 'marquee', 'hero-marquee'];
if (a.href.includes('.mp4') && bgBlocks.some((b) => a.closest(`.${b}`))) {
a.classList.add('hide');
const { href, hash, dataset } = a;
const attrs = getVideoAttrs(hash || 'autoplay', dataset);
const video = `<video ${attrs}>
<source src="${href}" type="video/mp4" />
</video>`;
if (!a.parentNode) return;
a.insertAdjacentHTML('afterend', video);
const videoElem = document.body.querySelector(`source[src="${href}"]`)?.parentElement;
applyHoverPlay(videoElem);
a.remove();
turnAnchorIntoVideo({
hash: a.hash || 'autoplay',
src: a.href,
anchorTag: a,
});
} else {
const embed = `<div class="milo-video">
<iframe src="${a.href}" class="adobetv" webkitallowfullscreen mozallowfullscreen allowfullscreen scrolling="no" allow="encrypted-media" title="Adobe Video Publishing Cloud Player" loading="lazy">
Expand All @@ -25,17 +19,4 @@ const loadAdobeTv = (a) => {
a.insertAdjacentHTML('afterend', embed);
a.remove();
}
};

export default function init(a) {
a.classList.add('hide-video');
if (a.textContent.includes('no-lazy')) {
loadAdobeTv(a);
} else {
createIntersectionObserver({
el: a,
options: { rootMargin: `${ROOT_MARGIN}px` },
callback: loadAdobeTv,
});
}
}
4 changes: 2 additions & 2 deletions libs/blocks/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export function getHashParams(hashStr) {
params.hash = part;
} else {
const [key, val] = part.split('=');
if (key === 'delay' && parseInt(val, 10) > 0) {
if (key === 'delay') {
params.delay = parseInt(val, 10) * 1000;
}
}
Expand All @@ -232,7 +232,7 @@ export function getHashParams(hashStr) {

export function delayedModal(el) {
const { hash, delay } = getHashParams(el?.dataset.modalHash);
if (!delay || !hash) return false;
if (delay === undefined || !hash) return false;
isDelayedModal = true;
const modalOpenEvent = new Event(`${hash}:modalOpen`);
const pagesModalWasShownOn = window.sessionStorage.getItem(`shown:${hash}`);
Expand Down
41 changes: 11 additions & 30 deletions libs/blocks/video/video.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createIntersectionObserver, getConfig } from '../../utils/utils.js';
import { applyHoverPlay, getVideoAttrs, applyInViewPortPlay } from '../../utils/decorate.js';
import { getConfig } from '../../utils/utils.js';
import { turnAnchorIntoVideo } from '../../utils/decorate.js';

const ROOT_MARGIN = 1000;

const loadVideo = (a) => {
const { pathname, hash, dataset } = a;
export default function init(a) {
a.classList.add('hide-video');
if (!a.parentNode) return;
const { pathname } = a;
let videoPath = `.${pathname}`;
if (pathname.match('media_.*.mp4')) {
const { codeRoot } = getConfig();
Expand All @@ -14,28 +14,9 @@ const loadVideo = (a) => {
const mediaFilename = pathname.split('/').pop();
videoPath = `${root}${mediaFilename}`;
}

const attrs = getVideoAttrs(hash, dataset);
const video = `<video ${attrs}>
<source src="${videoPath}" type="video/mp4" />
</video>`;
if (!a.parentNode) return;
a.insertAdjacentHTML('afterend', video);
const videoElem = document.body.querySelector(`source[src="${videoPath}"]`)?.parentElement;
applyHoverPlay(videoElem);
applyInViewPortPlay(videoElem);
a.remove();
};

export default function init(a) {
a.classList.add('hide-video');
if (a.textContent.includes('no-lazy')) {
loadVideo(a);
} else {
createIntersectionObserver({
el: a,
options: { rootMargin: `${ROOT_MARGIN}px` },
callback: loadVideo,
});
}
turnAnchorIntoVideo({
hash: a.hash,
src: videoPath,
anchorTag: a,
});
}
4 changes: 2 additions & 2 deletions libs/deps/imslib.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libs/features/personalization/entitlements.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getConfig } from '../../utils/utils.js';

const ENTITLEMENT_MAP = {
'51b1f617-2e43-4e91-a98a-3b7716ecba8f': 'photoshop-any',
'31943c06-06de-4f5f-8689-18973c13207a': 'photoshop-any',
'8ba78b22-90fb-4b97-a1c4-f8c03a45cbc2': 'indesign-any',
'8d3c8ac2-2937-486b-b6ff-37f02271b09b': 'illustrator-any',
'fd30e9c7-9ae9-44db-8e70-5c652a5bb1d2': 'cc-all-apps-any',
Expand Down
19 changes: 12 additions & 7 deletions libs/features/personalization/personalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,11 @@ export function handleCommands(commands, rootEl = document, forceInline = false)
});
}

const getVariantInfo = (line, variantNames, variants, manifestPath, manifestOverrideName) => {
const getVariantInfo = (line, variantNames, variants, manifestPath, fTargetId) => {
const config = getConfig();
let manifestId = getFileName(manifestPath);
let targetId = manifestId.replace('.json', '');
if (manifestOverrideName) targetId = manifestOverrideName;
if (fTargetId) targetId = fTargetId;
if (!config.mep?.preview) manifestId = false;
const action = line.action?.toLowerCase().replace('content', '').replace('fragment', '');
const { selector } = line;
Expand Down Expand Up @@ -508,7 +508,7 @@ const getVariantInfo = (line, variantNames, variants, manifestPath, manifestOver
});
};

export function parseManifestVariants(data, manifestPath, manifestOverrideName) {
export function parseManifestVariants(data, manifestPath, targetId) {
if (!data?.length) return null;

const manifestConfig = {};
Expand All @@ -524,7 +524,7 @@ export function parseManifestVariants(data, manifestPath, manifestOverrideName)
});

experiences.forEach((line) => {
getVariantInfo(line, variantNames, variants, manifestPath, manifestOverrideName);
getVariantInfo(line, variantNames, variants, manifestPath, targetId);
});

manifestConfig.variants = variants;
Expand All @@ -545,6 +545,7 @@ function parsePlaceholders(placeholders, config, selectedVariantName = '') {
if (!placeholders?.length || selectedVariantName === 'default') return config;
const valueNames = [
selectedVariantName.toLowerCase(),
config.mep?.geoPrefix,
config.locale.region.toLowerCase(),
config.locale.ietf.toLowerCase(),
...config.locale.ietf.toLowerCase().split('-'),
Expand Down Expand Up @@ -684,8 +685,9 @@ export async function getManifestConfig(info, variantOverride = false) {
acc[item.key] = item.value;
return acc;
}, {});
const manifestOverrideName = name || infoObj?.['manifest-override-name']?.toLowerCase();
const manifestConfig = parseManifestVariants(persData, manifestPath, manifestOverrideName);
const manifestOverrideName = infoObj?.['manifest-override-name']?.toLowerCase();
const targetId = name || manifestOverrideName;
const manifestConfig = parseManifestVariants(persData, manifestPath, targetId);

if (!manifestConfig) {
/* c8 ignore next 3 */
Expand All @@ -697,8 +699,10 @@ export async function getManifestConfig(info, variantOverride = false) {
'manifest-execution-order': ['First', 'Normal', 'Last'],
};
if (infoTab) {
manifestConfig.manifestOverrideName = manifestOverrideName;
manifestConfig.manifestType = infoObj?.['manifest-type']?.toLowerCase();
if (manifestOverrideName && manifestConfig.manifestType === TRACKED_MANIFEST_TYPE) {
manifestConfig.manifestOverrideName = manifestOverrideName;
}
const executionOrder = {
'manifest-type': 1,
'manifest-execution-order': 1,
Expand Down Expand Up @@ -955,6 +959,7 @@ export async function init(enablements = {}) {
highlight: (mepHighlight !== undefined && mepHighlight !== 'false'),
targetEnabled: target,
experiments: [],
geoPrefix: config.locale?.prefix.split('/')[1]?.toLowerCase() || 'en-us',
};
manifests = manifests.concat(await combineMepSources(pzn, promo, mepParam));
manifests?.forEach((manifest) => {
Expand Down
10 changes: 5 additions & 5 deletions libs/features/personalization/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ function createPreviewPill(manifests) {
manifestUrl,
manifestOverrideName,
} = manifest;
const editUrl = manifestUrl || manifestPath;
let radio = '';
variantNames.forEach((variant) => {
const checked = {
Expand Down Expand Up @@ -180,18 +181,18 @@ function createPreviewPill(manifests) {
<p>On: ${manifest.event.start?.toLocaleString()} - <a target= "_blank" href="?instant=${manifest.event.start?.toISOString()}">instant</a></p>
<p>Off: ${manifest.event.end?.toLocaleString()}</p>` : '';
let analyticsTitle = '';
if (manifestType === TRACKED_MANIFEST_TYPE) {
if (manifestType !== TRACKED_MANIFEST_TYPE) {
analyticsTitle = 'N/A for this manifest type';
} else if (manifestOverrideName) {
analyticsTitle = manifestOverrideName;
} else {
analyticsTitle = manifestFileName.replace('.json', '').slice(0, 20);
}
manifestList += `<div class="mep-manifest-info" title="Full url: ${manifestUrl}&#013;Analytics manifest name: ${analyticsTitle}">
manifestList += `<div class="mep-manifest-info" title="Manifest location: ${editUrl}&#013;Analytics manifest name: ${analyticsTitle}">
<div class="mep-manifest-title">
${targetTitle}
<i></i>
<a class="mep-edit-manifest" data-manifest-url="${manifestUrl}" data-manifest-path="${manifestPath}" target="_blank" title="Open manifest">
<a class="mep-edit-manifest" data-manifest-url="${editUrl}" data-manifest-path="${editUrl}" target="_blank" title="Open manifest">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="16px" height="16px" fill-rule="nonzero"><g transform=""><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(8.53333,8.53333)"><path d="M22.82813,3c-0.51175,0 -1.02356,0.19544 -1.41406,0.58594l-2.41406,2.41406l5,5l2.41406,-2.41406c0.781,-0.781 0.781,-2.04713 0,-2.82812l-2.17187,-2.17187c-0.3905,-0.3905 -0.90231,-0.58594 -1.41406,-0.58594zM17,8l-11.74023,11.74023c0,0 0.91777,-0.08223 1.25977,0.25977c0.342,0.342 0.06047,2.58 0.48047,3c0.42,0.42 2.64389,0.12436 2.96289,0.44336c0.319,0.319 0.29688,1.29688 0.29688,1.29688l11.74023,-11.74023zM4,23l-0.94336,2.67188c-0.03709,0.10544 -0.05623,0.21635 -0.05664,0.32813c0,0.55228 0.44772,1 1,1c0.11177,-0.00041 0.22268,-0.01956 0.32813,-0.05664c0.00326,-0.00128 0.00652,-0.00259 0.00977,-0.00391l0.02539,-0.00781c0.00196,-0.0013 0.00391,-0.0026 0.00586,-0.00391l2.63086,-0.92773l-1.5,-1.5z"></path></g></g></g></svg>
</a>
${scheduled}
Expand Down Expand Up @@ -228,8 +229,7 @@ function createPreviewPill(manifests) {
<div class="mep-manifest-page-info-title">Page Info:</div>
<div>Target integration feature is ${targetOnText}</div>
<div>Personalization feature is ${personalizationOnText}</div>
<div>Page's Region is ${config.locale.region}</div>
<div>Page's Locale is ${config.locale.ietf}</div>
<div>Page's Prefix/Region/Locale are ${config.mep.geoPrefix} / ${config.locale.region} / ${config.locale.ietf}</div>
</div>
</div>
<div class="mep-manifest-list">
Expand Down
2 changes: 1 addition & 1 deletion libs/features/personalization/stage-entitlements.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const STAGE_ENTITLEMENTS = {
'5a5fd14e-f4ca-49d2-9f87-835df5477e3c': 'photoshop-any',
'22ec76d1-b715-4ec5-8f36-b0db7c8b725a': 'photoshop-any',
'09bc4ba3-ebed-4d05-812d-a1fb1a7e82ae': 'indesign-any',
'25ede755-7181-4be2-801e-19f157c005ae': 'illustrator-any',
'bf632803-4412-463d-83c5-757dda3224ee': 'cc-all-apps-any',
Expand Down
24 changes: 21 additions & 3 deletions libs/utils/decorate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createTag } from './utils.js';
import { createTag, createIntersectionObserver } from './utils.js';

export function decorateButtons(el, size) {
const buttons = el.querySelectorAll('em a, strong a, p > a strong');
Expand Down Expand Up @@ -229,7 +229,7 @@ export function handleObjectFit(bgRow) {
});
}

export function getVideoIntersectionObserver() {
function getVideoIntersectionObserver() {
if (!window?.videoIntersectionObs) {
window.videoIntersectionObs = new window.IntersectionObserver((entries) => {
entries.forEach((entry) => {
Expand All @@ -250,7 +250,7 @@ export function getVideoIntersectionObserver() {
return window.videoIntersectionObs;
}

export function applyInViewPortPlay(video) {
function applyInViewPortPlay(video) {
if (!video) return;
if (video.hasAttribute('data-play-viewport')) {
const observer = getVideoIntersectionObserver();
Expand All @@ -260,3 +260,21 @@ export function applyInViewPortPlay(video) {
observer.observe(video);
}
}

export function turnAnchorIntoVideo({ hash, src, anchorTag }) {
const { dataset, parentElement } = anchorTag;
const attrs = getVideoAttrs(hash, dataset);
const video = `<video ${attrs}></video>`;
anchorTag.insertAdjacentHTML('afterend', video);
const videoEl = parentElement.querySelector('video');
createIntersectionObserver({
el: parentElement,
options: { rootMargin: '1000px' },
callback: () => {
videoEl?.appendChild(createTag('source', { src, type: 'video/mp4' }));
},
});
applyHoverPlay(videoEl);
applyInViewPortPlay(videoEl);
anchorTag.remove();
}
26 changes: 23 additions & 3 deletions libs/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -730,10 +730,30 @@ async function decorateIcons(area, config) {
async function decoratePlaceholders(area, config) {
const el = area.querySelector('main') || area;
const regex = /{{(.*?)}}|%7B%7B(.*?)%7D%7D/g;
const found = regex.test(el.innerHTML);
if (!found) return;
const walker = document.createTreeWalker(
el,
NodeFilter.SHOW_TEXT,
{
acceptNode(node) {
const a = regex.test(node.nodeValue) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
regex.lastIndex = 0;
return a;
},
},
);
const nodes = [];
let node = walker.nextNode();
while (node !== null) {
nodes.push(node);
node = walker.nextNode();
}
if (!nodes.length) return;
const { replaceText } = await import('../features/placeholders.js');
el.innerHTML = await replaceText(el.innerHTML, config, regex);
const replaceNodes = nodes.map(async (textNode) => {
textNode.nodeValue = await replaceText(textNode.nodeValue, config, regex);
textNode.nodeValue = textNode.nodeValue.replace(/&nbsp;/g, '\u00A0');
});
await Promise.all(replaceNodes);
}

async function loadFooter() {
Expand Down
11 changes: 0 additions & 11 deletions test/blocks/adobetv/adobetv.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@ document.body.innerHTML = await readFile({ path: './mocks/body.html' });
const { default: init } = await import('../../../libs/blocks/adobetv/adobetv.js');

describe('adobetv autoblock', () => {
it('decorates no-lazy video', async () => {
const block = document.querySelector('.video.no-lazy');
const a = block.querySelector('a');
a.textContent = 'no-lazy';
block.append(a);

init(a);
const video = await waitForElement('.video.no-lazy iframe');
expect(video).to.exist;
});

it('creates video block', async () => {
const wrapper = document.body.querySelector('.adobe-tv');
const a = wrapper.querySelector(':scope > a');
Expand Down
2 changes: 1 addition & 1 deletion test/blocks/adobetv/mocks/body.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<main>
<div class="video no-lazy">
<div class="video">
<a href="https://video.tv.adobe.com/v/3410934t1">
https://video.tv.adobe.com/v/3410934t1
</a>
Expand Down
21 changes: 17 additions & 4 deletions test/blocks/marquee/marquee.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { readFile } from '@web/test-runner-commands';
import { expect } from '@esm-bundle/chai';
import sinon from 'sinon';
import { waitForElement } from '../../helpers/waitfor.js';
import { setConfig } from '../../../libs/utils/utils.js';
import { waitFor, waitForElement } from '../../helpers/waitfor.js';
import { setConfig, loadStyle } from '../../../libs/utils/utils.js';
import { loadMnemonicList } from '../../../libs/blocks/marquee/marquee.js';

const locales = { '': { ietf: 'en-US', tk: 'hah7vzn.css' } };
Expand All @@ -16,6 +16,15 @@ const video = await readFile({ path: './mocks/video.html' });
const multipleIcons = await readFile({ path: './mocks/multiple-icons.html' });

describe('marquee', () => {
before(async () => {
await new Promise((resolve) => {
loadStyle('../../../../libs/styles/styles.css', resolve);
});
await new Promise((resolve) => {
loadStyle('../../../../libs/blocks/marquee/marquee.css', resolve);
});
});

const marquees = document.querySelectorAll('.marquee');
marquees.forEach((marquee) => {
init(marquee);
Expand Down Expand Up @@ -69,7 +78,9 @@ describe('marquee', () => {
init(marquee);
videoBLock(document.querySelector('#single-background a[href*=".mp4"]'));
const videoEl = await waitForElement('#single-background .background video');
expect(videoEl).to.exist;
const intersectionObserverAddsSource = () => videoEl.querySelector('source');
await waitFor(intersectionObserverAddsSource);
expect(videoEl.querySelector('source')).to.exist;
document.getElementById('single-background').remove();
});

Expand All @@ -78,7 +89,9 @@ describe('marquee', () => {
init(marquee);
document.querySelectorAll('#multiple-background a[href*=".mp4"]').forEach((videoLink) => videoBLock(videoLink));
await waitForElement('#multiple-background .background video');
expect(marquee.querySelectorAll('.background video').length).to.equal(1);
const intersectionObserverAddsSource = () => document.querySelector('.background video source');
await waitFor(intersectionObserverAddsSource);
expect(marquee.querySelectorAll('.background video source').length).to.equal(1);
document.getElementById('multiple-background').remove();
});

Expand Down
Loading
Loading