Skip to content

Commit

Permalink
[Release] Stage to Main (adobecom#2821)
Browse files Browse the repository at this point in the history
  • Loading branch information
milo-pr-merge[bot] authored Sep 5, 2024
2 parents 91afbee + 264c998 commit 95fb526
Show file tree
Hide file tree
Showing 24 changed files with 500 additions and 57 deletions.
4 changes: 4 additions & 0 deletions libs/blocks/global-navigation/global-navigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,10 @@ header.global-navigation {
background-color: var(--feds-background-link--hover);
}

.feds-utilities .unav-comp-profile .secondary-button{
line-height: inherit;
}

#feds-googleLogin {
position: absolute;
top: 100%;
Expand Down
4 changes: 2 additions & 2 deletions libs/blocks/global-navigation/global-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,15 @@ class Gnav {
isDesktop.addEventListener('change', closeAllDropdowns);
}, 'Error in global navigation init', 'errorType=error,module=gnav');

ims = async () => loadIms()
ims = async () => (window.adobeIMS?.initialized ? this.imsReady() : loadIms()
.then(() => this.imsReady())
.catch((e) => {
if (e?.message === 'IMS timeout') {
window.addEventListener('onImsLibInstance', () => this.imsReady());
return;
}
lanaLog({ message: 'GNAV: Error with IMS', e, tags: 'errorType=info,module=gnav' });
});
}));

decorateTopNav = () => {
this.elements.mobileToggle = this.decorateToggle();
Expand Down
7 changes: 5 additions & 2 deletions libs/blocks/merch/merch.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,16 @@ async function openExternalModal(url, getModal) {
});
}

const isInternalModal = (url) => /\/fragments\//.test(url);

export async function openModal(e, url, offerType) {
e.preventDefault();
e.stopImmediatePropagation();
const { getModal } = await import('../modal/modal.js');
await import('../modal/modal.merch.js');
const offerTypeClass = offerType === OFFER_TYPE_TRIAL ? 'twp' : 'crm';
let modal;
if (/\/fragments\//.test(url)) {
if (isInternalModal(url)) {
const fragmentPath = url.split(/hlx.(page|live)/).pop();
modal = await openFragmentModal(fragmentPath, getModal);
} else {
Expand All @@ -398,7 +400,8 @@ export async function getModalAction(offers, options) {
const columnName = (offerType === OFFER_TYPE_TRIAL) ? FREE_TRIAL_PATH : BUY_NOW_PATH;
let url = checkoutLinkConfig[columnName];
if (!url) return undefined;
url = localizeLink(checkoutLinkConfig[columnName]);
url = isInternalModal(url)
? localizeLink(checkoutLinkConfig[columnName]) : checkoutLinkConfig[columnName];
return { url, handler: (e) => openModal(e, url, offerType) };
}

Expand Down
56 changes: 56 additions & 0 deletions libs/blocks/vimeo/vimeo.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,59 @@
position: relative;
padding-bottom: 56.25%;
}

lite-vimeo {
aspect-ratio: 16 / 9;
background-color: #000;
position: relative;
display: block;
contain: content;
background-position: center center;
background-size: cover;
cursor: pointer;
}

lite-vimeo > .ltv-playbtn {
font-size: 10px;
padding: 0;
width: 6.5em;
height: 4em;
background: rgb(23, 35, 34, 75%);
z-index: 1;
opacity: .8;
border-radius: .5em;
transition: opacity .2s ease-out, background .2s ease-out;
outline: 0;
border: 0;
cursor: pointer;
}

lite-vimeo:hover > .ltv-playbtn {
background-color: rgb(0, 173, 239);
opacity: 1;
}

lite-vimeo > .ltv-playbtn::before {
content: '';
border-style: solid;
border-width: 10px 0 10px 20px;
border-color: transparent transparent transparent #fff;
}

lite-vimeo > .ltv-playbtn,
lite-vimeo > .ltv-playbtn::before {
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
}

lite-vimeo.ltv-activated {
cursor: unset;
}

lite-vimeo.ltv-activated::before,
lite-vimeo.ltv-activated > .ltv-playbtn {
opacity: 0;
pointer-events: none;
}
89 changes: 72 additions & 17 deletions libs/blocks/vimeo/vimeo.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,80 @@
import { createIntersectionObserver, createTag, isInTextNode } from '../../utils/utils.js';
// part of the code is an optimized version of lite-vimeo-embed -> https://github.com/luwes/lite-vimeo-embed
import { replaceKey } from '../../features/placeholders.js';
import { createIntersectionObserver, createTag, getConfig, isInTextNode, loadLink } from '../../utils/utils.js';

export default function init(a) {
if (isInTextNode(a)) return;
const embedVimeo = () => {
const url = new URL(a.href);
let src = url.href;
if (url.hostname !== 'player.vimeo.com') {
const video = url.pathname.split('/')[1];
src = `https://player.vimeo.com/video/${video}?app_id=122963`;
}
const iframe = createTag('iframe', {
src,
style: 'border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;',
class LiteVimeo extends HTMLElement {
static preconnected = false;

connectedCallback() {
this.isMobile = navigator.userAgent.includes('Mobi');
this.videoId = this.getAttribute('videoid');
this.setupThumbnail();
this.setupPlayButton();
this.addEventListener('pointerover', LiteVimeo.warmConnections, { once: true });
this.addEventListener('click', this.addIframe);
}

static warmConnections() {
if (LiteVimeo.preconnected) return;
LiteVimeo.preconnected = true;
['player.vimeo.com',
'i.vimeocdn.com',
'f.vimeocdn.com',
'fresnel.vimeocdn.com',
].forEach((url) => loadLink(`https://${url}`, { rel: 'preconnect' }));
}

setupThumbnail() {
const { width, height } = this.getBoundingClientRect();
const roundedWidth = Math.min(Math.ceil(width / 100) * 100, 1920);
const roundedHeight = Math.round((roundedWidth / width) * height);

fetch(`https://vimeo.com/api/v2/video/${this.videoId}.json`)
.then((response) => response.json())
.then((data) => {
const thumbnailUrl = data[0]?.thumbnail_large?.replace(/-d_[\dx]+$/i, `-d_${roundedWidth}x${roundedHeight}`);
this.style.backgroundImage = `url("${thumbnailUrl}")`;
})
.catch((e) => {
window.lana.log(`Error fetching Vimeo thumbnail: ${e}`, { tags: 'errorType=info,module=vimeo' });
});
}

async setupPlayButton() {
const playBtnEl = createTag('button', {
type: 'button',
'aria-label': `${await replaceKey('play-video', getConfig())}`,
class: 'ltv-playbtn',
});
this.append(playBtnEl);
}

addIframe() {
if (this.classList.contains('ltv-activated')) return;
this.classList.add('ltv-activated');
const iframeEl = createTag('iframe', {
style: 'border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute; background-color: #000;',
frameborder: '0',
allow: 'autoplay; fullscreen; picture-in-picture',
allowfullscreen: 'true',
title: 'Content from Vimeo',
loading: 'lazy',
allow: 'accelerometer; fullscreen; autoplay; encrypted-media; gyroscope; picture-in-picture',
allowFullscreen: true,
src: `https://player.vimeo.com/video/${encodeURIComponent(this.videoId)}?autoplay=1&muted=${this.isMobile ? 1 : 0}`,
});
const wrapper = createTag('div', { class: 'embed-vimeo' }, iframe);
this.insertAdjacentElement('afterend', iframeEl);
iframeEl.addEventListener('load', () => iframeEl.focus(), { once: true });
this.remove();
}
}

export default async function init(a) {
if (isInTextNode(a)) return;
if (!customElements.get('lite-vimeo')) customElements.define('lite-vimeo', LiteVimeo);

const embedVimeo = () => {
const url = new URL(a.href);
const videoid = url.pathname.split('/')[url.hostname === 'player.vimeo.com' ? 2 : 1];
const liteVimeo = createTag('lite-vimeo', { videoid });
const wrapper = createTag('div', { class: 'embed-vimeo' }, liteVimeo);
a.parentElement.replaceChild(wrapper, a);
};

Expand Down
55 changes: 55 additions & 0 deletions libs/blocks/youtube/youtube.css
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
@import url('../../styles/iframe.css');

lite-youtube {
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
cursor: pointer;
}

lite-youtube > .lty-playbtn {
display: block;
width: 68px;
height: 48px;
position: absolute;
cursor: pointer;
transform: translate3d(-50%, -50%, 0);
top: 50%;
left: 50%;
z-index: 1;
background-color: transparent;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="red"/><path d="M45 24 27 14v20" fill="white"/></svg>');
filter: grayscale(100%);
transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
border: none;
}

lite-youtube:hover > .lty-playbtn,
lite-youtube .lty-playbtn:focus {
filter: none;
}

lite-youtube.lyt-activated {
cursor: unset;
}

lite-youtube.lyt-activated::before,
lite-youtube.lyt-activated > .lty-playbtn {
opacity: 0;
pointer-events: none;
}

.lyt-visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}

.dark-background {
background-color: #000;
}
105 changes: 89 additions & 16 deletions libs/blocks/youtube/youtube.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,109 @@
import { createIntersectionObserver, isInTextNode } from '../../utils/utils.js';
// part of the code is an optimized version of lite-youtube-embed -> https://github.com/paulirish/lite-youtube-embed
import { createIntersectionObserver, createTag, isInTextNode, loadLink } from '../../utils/utils.js';

class LiteYTEmbed extends HTMLElement {
connectedCallback() {
this.isMobile = navigator.userAgent.includes('Mobi');
this.videoId = this.getAttribute('videoid');
const playBtnEl = createTag('button', { type: 'button', class: 'lty-playbtn' });
this.append(playBtnEl);
this.playLabel = this.getAttribute('playlabel') || 'Play';
this.style.backgroundImage = `url("https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg")`;
this.style.backgroundSize = 'cover';
this.style.backgroundPosition = 'center';
const playBtnLabelEl = createTag('span', { class: 'lyt-visually-hidden' });
playBtnLabelEl.textContent = this.playLabel;
playBtnEl.append(playBtnLabelEl);
this.addEventListener('pointerover', LiteYTEmbed.warmConnections, { once: true });
this.addEventListener('click', this.addIframe);
this.needsYTApiForAutoplay = navigator.vendor.includes('Apple') || this.isMobile;
}

static warmConnections() {
if (LiteYTEmbed.preconnected) return;
LiteYTEmbed.preconnected = true;
['www.youtube-nocookie.com',
'www.google.com',
'googleads.g.doubleclick.net',
'static.doubleclick.net',
].forEach((url) => loadLink(`https://${url}`, { rel: 'preconnect' }));
}

static loadYouTubeAPI() {
return new Promise((resolve) => {
if (window.YT?.Player) {
resolve();
return;
}
const tag = createTag('script', { src: 'https://www.youtube.com/iframe_api' });
window.onYouTubeIframeAPIReady = resolve;
document.head.appendChild(tag);
});
}

async addIframe() {
if (this.classList.contains('lyt-activated')) return;

this.classList.add('lyt-activated');
const params = new URLSearchParams(this.getAttribute('params') || []);
params.append('autoplay', '1');
params.append('playsinline', '1');
if (this.isMobile) params.append('mute', '1');

if (this.needsYTApiForAutoplay) {
await LiteYTEmbed.loadYouTubeAPI();
await new Promise((resolve) => { window.YT.ready(resolve); });
// eslint-disable-next-line
new window.YT.Player(this, {
videoId: this.videoId,
playerVars: Object.fromEntries(params),
allow: 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture',
allowfullscreen: true,
title: this.playLabel,
});
} else {
const iframeEl = createTag('iframe', {
src: `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId)}?${params.toString()}`,
allowFullscreen: true,
allow: 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture',
title: this.playLabel,
});
this.insertAdjacentElement('afterend', iframeEl);
iframeEl.focus();
this.remove();
}
}
}

export default async function init(a) {
if (!customElements.get('lite-youtube')) customElements.define('lite-youtube', LiteYTEmbed);

export default function init(a) {
const embedVideo = () => {
if (isInTextNode(a) || !a.origin?.includes('youtu')) return;
const title = !a.textContent.includes('http') ? a.textContent : 'Youtube Video';
const searchParams = new URLSearchParams(a.search);
const id = searchParams.get('v') || a.pathname.split('/').pop();
searchParams.delete('v');
const src = `https://www.youtube.com/embed/${id}?${searchParams.toString()}`;
const embedHTML = `
<div class="milo-video">
<iframe src="${src}" class="youtube"
webkitallowfullscreen mozallowfullscreen allowfullscreen
allow="encrypted-media; accelerometer; gyroscope; picture-in-picture"
scrolling="no"
id="player-${id}"
title="${title}">
</iframe>
</div>`;
a.insertAdjacentHTML('afterend', embedHTML);
const liteYTElement = createTag('lite-youtube', { videoid: id, playlabel: title });

if (searchParams.toString()) liteYTElement.setAttribute('params', searchParams.toString());

const ytContainer = createTag('div', { class: 'milo-video dark-background' }, liteYTElement);
a.insertAdjacentElement('afterend', ytContainer);
a.remove();

if (document.readyState === 'complete') {
/* eslint-disable-next-line no-underscore-dangle */
// eslint-disable-next-line no-underscore-dangle
window._satellite?.track('trackYoutube');
} else {
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
/* eslint-disable-next-line no-underscore-dangle */
// eslint-disable-next-line no-underscore-dangle
window._satellite?.track('trackYoutube');
}
});
}
};

createIntersectionObserver({ el: a, callback: embedVideo });
}
Loading

0 comments on commit 95fb526

Please sign in to comment.