generated from adobe/aem-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MWPW-156244] Reduce TBT Youtube/Vimeo Videos (#2812)
* added facades for youtube & vimeo * added unit tests for youtube and vimeo * hotfix * implementing feedback * implementing feedback * fixed autoplay on mobile * made isMobile an instance property --------- Co-authored-by: milo-pr-merge[bot] <169241390+milo-pr-merge[bot]@users.noreply.github.com>
- Loading branch information
1 parent
b6cc0ca
commit 94f5513
Showing
8 changed files
with
362 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// eslint-disable-next-line | ||
export const replaceKey = () => 'placeholder'; |
Oops, something went wrong.