diff --git a/EXTERNAL_IMAGES.md b/EXTERNAL_IMAGES.md new file mode 100644 index 0000000000..3ec0441c78 --- /dev/null +++ b/EXTERNAL_IMAGES.md @@ -0,0 +1,45 @@ +# Using images from external URLs in AEM Franklin pages + +## Introduction +This document explains a mechanism for getting images served from external URLs on AEM Franklin pages. You may find this useful if you want to have your images served from an external assets repository. + +## Process +During the page authoring process, the author has to specify the external URL from which the image is served. This is done by placing external image links containing the hyperlinked publicly accessible image URLs on the Word/Google Document. The image links are then replaced with the actual images during the page rendering process. + +### Note for site authors +Here's [an example page and document](https://ext-images--franklin-assets-selector--hlxsites.hlx.page/external-images-example?view-doc-source=true) that shows how to use external images in AEM Franklin pages. +You can specify external images by just copying and pasting the image URL in the Word/Google Document. The image URL must be hyperlinked. If the hyperlink has an image file extension, it will be treated as an external image. If the hyperlink does not have an image file extension, it will be treated as a regular hyperlink. +Alternatively, you can also explicitly specify an external image marker and adding the external image url as a hyperlink in it. +The above [example page](https://ext-images--franklin-assets-selector--hlxsites.hlx.page/external-images-example?view-doc-source=true) demonstrates both the approaches. + +### Note for site developers +Anchor tags get treated as external images if their `textContent` is same as their `href` attribute and the URL specified in `href` is of an image file extension. For e.g. `'jpg', 'jpeg', 'png', 'gif', 'webp'`. Web optimized image formats such as `webp` should be preferred. You can find the implementation of this [here](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L105-L110) + +Alternatively, an *image marker* text can be used to explicitly indicate external images. This is a pre-configured value. You can configure it [here](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L227). + + +Also note that for creating optimized `picture` tags for external images, you must override `createOptimizedPicture` function. You can find a sample overidden implementation of `createOptimizedPicture` [here](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L142-L182). + +To summarize, most of the logic for this [is here](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L69-L218) and trigger point for it starts with `decorateExternalImages`. For e.g. [here with an implict external image decoration](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L229-L230). + +``` +export function decorateMain(main) { + // decorate external images with implicit external image detection + decorateExternalImages(main); + ... +} +``` + +And [here with an explicit external image marker](https://github.com/hlxsites/franklin-assets-selector/blob/9145aeac55512ec199152065b16db6c24cea3421/scripts/scripts.js#L226-L227). +``` +export function decorateMain(main) { + // decorate external images with explicit external image marker + decorateExternalImages(main, '//External Image//'); +... +} +``` + +## How does this work? +During the page rendering process, the frontend code replaces the anchor tags identified as exteernal images on the page with the `picture` tags with `src`/`srcset` attributes set as the external image's url as specified in the external image link placed on the Word / Google Document during the page authoring process. + +Authors can optionally specify query paramaters in the hyperlinked external url and they would be retained in the `picture` tag's `src`/`srcset` attributes. These are useful for specifying image delivery parameters such as image width, height, format, etc. as understood by the external image delivery service. \ No newline at end of file diff --git a/README.md b/README.md index fb797b6ad0..6adefa2645 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ -# Your Project's Title... -Your project's description... +# AEM Asset Selector for Franklin Authoring +Integration between AEM Asset Selector and AEM Franklin to make AEM assets available in Franklin site authoring. + +# High level flow + +[Link to Diagram Source](https://lucid.app/lucidchart/d6db1b7d-144f-4ac9-94a2-fce760ed2ca4/edit?viewport_loc=-368%2C-403%2C1899%2C1069%2C0_0&invitationId=inv_cd6848d0-dfc0-4be9-b0cb-3cae5a1ba757) + +![High Level Flow](/resources/using-asset-selector-with-franklin.jpeg) ## Environments - Preview: https://main--{repo}--{owner}.aem.page/ @@ -24,3 +30,18 @@ npm run lint 1. Install the [AEM CLI](https://github.com/adobe/helix-cli): `npm install -g @adobe/aem-cli` 1. Start AEM Proxy: `aem up` (opens your browser at `http://localhost:3000`) 1. Open the `{repo}` directory in your favorite IDE and start coding :) + +## Extending the Assets Selector Capabilities + +To extend the capabilities of the Assets Selector, you can look at the following sample configurations and GitHub repository as a reference. These configurations are hosted on Adobe IO Runtime through App Builder and can be adapted to fit your project needs and extension requirements. + +- [Sample Configuration Hosted on Adobe IO Runtime][0] +- [Sample Configuration with Web Path][1] +- [GitHub Reference Implementation][2] + +This configuration is particularly useful for extending the Assets Selector capabilities documented [here][3]. Feel free to integrate and customize it as per your project’s use cases. + +[0]: https://245265-extensionconfig.adobeioruntime.net/api/v1/web/extension-config/extension-config +[1]: https://245265-extensionconfig.adobeioruntime.net/api/v1/web/extension-config/extension-config?webPath=snorkling +[2]: https://github.com/Adobe-Marketing-Cloud/assets-selector-extension +[3]: https://www.aem.live/developer/configuring-aem-assets-sidekick-plugin#extend-aem-assets-sidekick-plugin diff --git a/blocks/embed/embed.css b/blocks/embed/embed.css new file mode 100644 index 0000000000..c002a23647 --- /dev/null +++ b/blocks/embed/embed.css @@ -0,0 +1,62 @@ +main .embed { + width: unset; + text-align: center; + max-width: 800px; + margin: 32px auto; + } + + main .embed > div { + display: flex; + justify-content: center; + } + + main .embed.embed-twitter .twitter-tweet-rendered { + margin-left: auto; + margin-right: auto; + } + + main .embed .embed-placeholder { + width: 100%; + aspect-ratio: 16 / 9; + position: relative; + } + + main .embed .embed-placeholder > * { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + inset: 0; + } + + main .embed .embed-placeholder picture img { + width: 100%; + height: 100%; + object-fit: cover; + } + + main .embed .embed-placeholder-play button { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(3); + width: 22px; + height: 22px; + border: 2px solid; + border-radius: 20px; + padding: 0; + } + + main .embed .embed-placeholder-play button::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 0; + height: 10px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 6px solid; + top: 4px; + left: 7px; + } \ No newline at end of file diff --git a/blocks/embed/embed.js b/blocks/embed/embed.js new file mode 100644 index 0000000000..c9f3e25286 --- /dev/null +++ b/blocks/embed/embed.js @@ -0,0 +1,113 @@ +/* + * Embed Block + * Show videos and social posts directly on your page + * https://www.hlx.live/developer/block-collection/embed + */ + +const loadScript = (url, callback, type) => { + const head = document.querySelector('head'); + const script = document.createElement('script'); + script.src = url; + if (type) { + script.setAttribute('type', type); + } + script.onload = callback; + head.append(script); + return script; +}; + +const getDefaultEmbed = (url) => `
`; + loadScript('https://platform.twitter.com/widgets.js'); + return embedHTML; +}; + +const loadEmbed = (block, link, autoplay) => { + if (block.classList.contains('embed-is-loaded')) { + return; + } + + const EMBEDS_CONFIG = [ + { + match: ['youtube', 'youtu.be'], + embed: embedYoutube, + }, + { + match: ['vimeo'], + embed: embedVimeo, + }, + { + match: ['twitter'], + embed: embedTwitter, + }, + ]; + + const config = EMBEDS_CONFIG.find((e) => e.match.some((match) => link.includes(match))); + const url = new URL(link); + if (config) { + block.innerHTML = config.embed(url, autoplay); + block.classList = `block embed embed-${config.match[0]}`; + } else { + block.innerHTML = getDefaultEmbed(url); + block.classList = 'block embed'; + } + block.classList.add('embed-is-loaded'); +}; + +export default function decorate(block) { + const placeholder = block.querySelector('picture'); + const link = block.querySelector('a').href; + block.textContent = ''; + + if (placeholder) { + const wrapper = document.createElement('div'); + wrapper.className = 'embed-placeholder'; + wrapper.innerHTML = ''; + wrapper.prepend(placeholder); + wrapper.addEventListener('click', () => { + loadEmbed(block, link, true); + }); + block.append(wrapper); + } else { + const observer = new IntersectionObserver((entries) => { + if (entries.some((e) => e.isIntersecting)) { + observer.disconnect(); + loadEmbed(block, link); + } + }); + observer.observe(block); + } +} diff --git a/blocks/hotspot/hotspot.css b/blocks/hotspot/hotspot.css new file mode 100644 index 0000000000..37c36415a6 --- /dev/null +++ b/blocks/hotspot/hotspot.css @@ -0,0 +1,74 @@ +/* CSS: styles.css */ +.block.hotspot { + position: relative; + background: none; +} + +.block.hotspot img { + max-width: 100%; + width: auto; + height: auto; +} + +.block.hotspot > div.hotspot { + background: red; /* Temporary for visibility */ + z-index: 10; /* Ensure it is above the image */ + width: 20px; + height: 20px; + border-radius: 100%; + border: 3px solid white; + position: absolute; + cursor: pointer; +} + +.block.hotspot img, +.block.hotspot video { + max-width: 100%; + width: auto; + height: auto; +} + +.block.hotspot > div.hotspot .hotspot-content { + display: none; /* Hidden by default */ + position: absolute; + top: -10px; /* Adjust positioning as needed */ + left: 50%; + transform: translateX(-50%); + padding: 10px; + border-radius: 5px; + z-index: 15; + width: 200px; /* Adjust size as needed */ +} + +.block.hotspot > div.hotspot .hotspot-content.bgborder { + background: white; + border: 1px solid white; +} + +.block.hotspot > div.hotspot.onclick .hotspot-content, +.block.hotspot > div.hotspot:hover .hotspot-content { + display: block; /* Show on click or hover */ +} + +.block.hotspot > div.hotspot .hotspot-content img, +.block.hotspot > div.hotspot .hotspot-content video { + width: 400px; + height: auto; + max-width: unset; +} + +.block.hotspot > div.hotspot .hotspot-content video { + max-height: 150px; /* Adjust as needed */ +} + +.block.hotspot > div.hotspot:hover::after, +.block.hotspot > div.hotspot.onclick::after { + opacity: 1; +} + +.block.hotspot svg { + position: absolute; + top: 0; + left: 0; + z-index: 0; +} diff --git a/blocks/hotspot/hotspot.js b/blocks/hotspot/hotspot.js new file mode 100644 index 0000000000..dfbdc1157a --- /dev/null +++ b/blocks/hotspot/hotspot.js @@ -0,0 +1,75 @@ +export default function decorate(block) { + [...block.children].forEach((row, r) => { + if (r > 0) { + const content = [...row.children][0].textContent.trim(); + const variant = block.classList.value; + const isImageVariant = variant.includes('image') && !(variant.includes('video')); + const isVideoVariant = variant.includes('video') && !(variant.includes('image')); + const isTextVariant = !isImageVariant && !isVideoVariant; + + const nexticondiv = document.createElement('div'); + nexticondiv.classList.add('hotspot'); // Added class for CSS targeting + nexticondiv.style.left = [...row.children][1].textContent; + nexticondiv.style.top = [...row.children][2].textContent; + nexticondiv.setAttribute('data', content); + + // Create content display element + const contentContainer = document.createElement('div'); + contentContainer.classList.add('hotspot-content'); + + if (isImageVariant) { + const img = document.createElement('img'); + img.src = content; + contentContainer.appendChild(img); + } else if (isVideoVariant) { + const video = document.createElement('div'); + const allowedVideoDomains = ['youtube.com', 'vimeo.com', 'sidekick-library--aem-block-collection--adobe']; + try { + const url = new URL(content); + // the below code can be updated to include more video hosting sites + const domainCheck = (domain) => url.hostname.includes(domain); + const isTrustedDomain = allowedVideoDomains.some(domainCheck); + if (isTrustedDomain) { + const div = document.createElement('div'); + div.className = 'embed-default'; + + const iframe = document.createElement('iframe'); + iframe.src = url.href; + iframe.setAttribute('allow', 'encrypted-media'); + iframe.setAttribute('loading', 'lazy'); + + div.appendChild(iframe); + video.appendChild(div); + } else { + video.textContent = 'This video source is not allowed.'; + contentContainer.classList.add('bgborder'); + } + } catch (e) { + video.textContent = 'Invalid video URL.'; + contentContainer.classList.add('bgborder'); + } + // above code can be updated for video controls such as autoplay, loop, etc. + contentContainer.appendChild(video); + } else if (isTextVariant) { + contentContainer.textContent = content; // Display text + contentContainer.classList.add('bgborder'); + } + + // Append content container to hotspot div + nexticondiv.appendChild(contentContainer); + nexticondiv.addEventListener('click', () => { + // Hide content of all other hotspots + document.querySelectorAll('.hotspot').forEach((hotspot) => { + if (hotspot !== nexticondiv) { + hotspot.classList.remove('onclick'); + } + }); + // Toggle the current hotspot content + nexticondiv.classList.toggle('onclick'); + }); + + row.after(nexticondiv); + row.remove(); + } + }); +} diff --git a/blocks/video/video.css b/blocks/video/video.css new file mode 100644 index 0000000000..55ad8b0721 --- /dev/null +++ b/blocks/video/video.css @@ -0,0 +1,298 @@ +main > .section.video-container { + padding: 0; +} + +.video-modal, +.video.block { + box-sizing: border-box; +} + +.video-modal > *, +.video.block > * { + box-sizing: inherit; +} + +.video-wrapper:has(.video.hero) { + max-width: unset; +} + +.video-hero { + position: relative; + overflow: hidden; + background-color: #53565a; + width: 100%; + height: calc(100vh - var(--nav-height)); +} + +.video-hero .video-hero-content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + gap: 16px; + padding: 24px; + color: #fff; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 500px; + z-index: 2; +} + +.video-hero .video-hero-title { + font-size: 4rem; + line-height: 1; + text-transform: uppercase; + margin: 0; +} + +.video-hero .video-hero-description { + font-size: 1.25rem; + font-weight: 400; + line-height: 1.5; + margin: 0; +} + +.video-hero .video-hero-button:any-link { + display: block; + background-color: #fff; + color: #141411; + padding: 12px 24px; + border-radius: 8px; + font-size: 1rem; + font-weight: 300; + letter-spacing: 3px; + text-transform: uppercase; + text-decoration: none; +} + +.video-hero > picture { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1; +} + +.video-hero > picture img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.video-component picture, +.video-component picture img { + display: block; + width: 100%; + height: 100%; +} + +.video-hero video, +.video-hero .vjs-poster img { + object-fit: cover; +} + +.custom-play-button { + position: absolute; + bottom: 18px; + right: 18px; + background-color: transparent; + width: 44px; + height: 44px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + padding: 0; + margin: 0; + border: 0; +} + +.custom-play-button .icon { + width: 32px; + height: 32px; +} + +.custom-play-button:hover, +.custom-play-button:focus { + background-color: transparent; +} + +.video-card-grid { + display: grid; + grid-template-columns: 1fr; + gap: 16px; + padding: 16px; + list-style: none; +} + +.video-card { + display: flex; + flex-direction: column; + background-color: #f7f7f7; + border-radius: 8px; + overflow: hidden; + position: relative; +} + +.video-card .video-container { + position: relative; + width: 100%; + aspect-ratio: 3 / 2; +} + +.video-card video, +.video-card .vjs-poster img { + object-fit: cover; +} + +.video-card picture { + display: block; + position: absolute; + top: 0; + left: 0; + z-index: 1; +} + +.video-card picture, +.video-card .video-container picture img { + width: 100%; + height: auto; + object-fit: cover; + aspect-ratio: 3 / 2; +} + +.video-modal .video-container { + border-radius: 8px; + overflow: hidden; +} + +.video-card .video-card-content { + display: flex; + flex-direction: column; + gap: 8px; + padding: 24px 34px; + overflow: hidden; +} + +.video-card .video-card-title { + font-size: 1.25rem; + font-weight: 700; + line-height: 1.2; + margin: 0; +} + +.video-card .video-card-description { + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + margin: 0; + color: #53565a; +} + +@media screen and (width >= 768px) { + .video-card-grid { + grid-template-columns: repeat(2, 1fr); + } + + .video-card-grid-item:nth-child(odd):last-child { + grid-column: 1 / -1; + } + + .video-card-grid-item:nth-child(odd):last-child .video-card { + display: flex; + flex-direction: row-reverse; + } + + .video-card-grid-item:nth-child(odd):last-child .video-container { + flex: 1 0 50%; + } + + .video-card-grid-item:nth-child(odd):last-child .video-card-content { + justify-content: center; + } +} + +.video-component { + position: relative; + width: 100%; + height: 100%; +} + +.video-component .video-play-button { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; + height: 60px; + width: 60px; + border-radius: 50%; + font-size: 16px; + cursor: pointer; + padding: 0; + margin: 0; +} + +.video-component .video-play-button:hover, +.video-component .video-play-button:focus { + background-color: #fff; +} + +.video-component .video-play-button .icon { + display: block; + width: 100%; + height: 100%; +} + +.video-modal-dialog[open] { + border: none; + width: 100%; + max-width: 1200px; + padding: 0; + overflow: auto; +} + +.video-modal-dialog::backdrop { + background-color: #fff; +} + +.video-modal { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 8px; +} + +.video-modal .video-modal-header, +.video-modal .video-modal-content { + position: relative; + padding: 10px; + width: 100%; +} + +.video-modal .video-modal-header { + height: 44px; +} + +.video-modal .video-modal-header .video-modal-close { + position: absolute; + top: 50%; + right: 10px; + transform: translateY(-50%); + background: transparent; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + border: 0; + padding: 10px; + margin: 0; + height: 40px; + width: 40px; +} diff --git a/blocks/video/video.js b/blocks/video/video.js new file mode 100644 index 0000000000..9316b14512 --- /dev/null +++ b/blocks/video/video.js @@ -0,0 +1,496 @@ +import { decorateIcons, loadScript, loadCSS } from '../../scripts/aem.js'; + +const VIDEO_JS_SCRIPT = '/blocks/video/videojs/video.min.js'; +const VIDEO_JS_CSS = '/blocks/video/videojs/video-js.min.css'; +const VIDEO_JS_LOAD_EVENT = 'videojs-loaded'; + +function getDeviceSpecificVideoUrl(videoUrl) { + const { userAgent } = navigator; + const isIOS = /iPad|iPhone|iPod/.test(userAgent); + const isSafari = (/Safari/i).test(userAgent) && !(/Chrome/i).test(userAgent) && !(/CriOs/i).test(userAgent) && !(/Android/i).test(userAgent) && !(/Edg/i).test(userAgent); + + const manifest = (isIOS || isSafari) ? 'manifest.m3u8' : 'manifest.mpd'; + return videoUrl.replace(/manifest\.mpd|manifest\.m3u8|play/, manifest); +} + +function parseConfig(block) { + const isAutoPlay = block.classList.contains('autoplay'); + + if (block.classList.contains('hero')) { + const posterImage = block.querySelector('picture'); + const videoUrl = block.querySelector('div > div:first-child a').href; + const title = block.querySelector('h1, h2, h3')?.textContent; + const description = block.querySelector('div > div:nth-child(2) > p')?.textContent; + const button = block.querySelector('div > div:nth-child(2) > p:last-child > a'); + + return { + type: 'hero', + videoUrl: getDeviceSpecificVideoUrl(videoUrl), + isAutoPlay, + title, + description, + button, + posterImage, + }; + } + + if (block.classList.contains('inline')) { + const cards = [...block.children].map((child) => { + const posterImage = child.querySelector('picture'); + const videoUrl = child.querySelector('div:first-child a').href; + const title = child.querySelector('h1, h2, h3')?.textContent; + const description = child.querySelector('div:nth-child(2) > p')?.textContent; + + return { + videoUrl: getDeviceSpecificVideoUrl(videoUrl), + isAutoPlay, + title, + description, + posterImage, + }; + }); + + return { + type: 'cards', + cards, + }; + } + + const videoUrl = block.querySelector('div:first-child a').href; + const posterImage = block.querySelector('picture'); + + return { + type: 'modal', + videoUrl: getDeviceSpecificVideoUrl(videoUrl), + posterImage, + }; +} + +function getVideojsScripts() { + return { + scriptTag: document.querySelector(`head > script[src="${VIDEO_JS_SCRIPT}"]`), + cssLink: document.querySelector(`head > link[href="${VIDEO_JS_CSS}"]`), + }; +} + +async function waitForVideoJs() { + return new Promise((resolve) => { + const { scriptTag, cssLink } = getVideojsScripts(); + const isJsLoaded = scriptTag && scriptTag.dataset.loaded; + const isCSSLoaded = cssLink && cssLink.dataset.loaded; + if (isJsLoaded && isCSSLoaded) { + resolve(); + } + + const successHandler = () => { + document.removeEventListener(VIDEO_JS_LOAD_EVENT, successHandler); + resolve(); + }; + + document.addEventListener(VIDEO_JS_LOAD_EVENT, successHandler); + }); +} + +async function loadVideoJs() { + const { scriptTag, cssLink } = getVideojsScripts(); + if (scriptTag && cssLink) { + await waitForVideoJs(); + return; + } + + await Promise.all([ + loadCSS(VIDEO_JS_CSS), + loadScript(VIDEO_JS_SCRIPT), + ]); + + const { scriptTag: jsScript, cssLink: css } = getVideojsScripts(); + jsScript.dataset.loaded = true; + css.dataset.loaded = true; + document.dispatchEvent(new Event(VIDEO_JS_LOAD_EVENT)); +} + +function createPlayButton(container, player) { + const pauseIcon = document.createElement('span'); + pauseIcon.classList.add('icon'); + pauseIcon.classList.add('icon-pause'); + + const playIcon = document.createElement('span'); + playIcon.classList.add('icon'); + playIcon.classList.add('icon-play'); + + const button = document.createElement('button'); + button.classList.add('custom-play-button'); + button.addEventListener('click', () => { + if (player.paused()) { + player.play(); + } else { + player.pause(); + } + }); + + button.append(pauseIcon); + button.append(playIcon); + + function updateIcons(isPaused) { + if (isPaused) { + playIcon.style.display = ''; + pauseIcon.style.display = 'none'; + button.setAttribute('aria-label', 'Play video'); + } else { + playIcon.style.display = 'none'; + pauseIcon.style.display = ''; + button.setAttribute('aria-label', 'Pause video'); + } + } + + player.on('play', () => { + updateIcons(false); + }); + player.on('pause', () => { + updateIcons(true); + }); + + decorateIcons(button); + updateIcons(player.paused()); + + container.append(button); +} + +function isImageFormatSupported(format) { + if (['image/jpeg', 'image/png'].includes(format)) { + return true; + } + + const elem = document.createElement('canvas'); + if (elem.getContext && elem.getContext('2d')) { + return elem.toDataURL(format).indexOf(`data:${format}`) === 0; + } + + return false; +} + +function getPosterImage(posterElement) { + const img = posterElement.querySelector('img'); + const sources = posterElement.querySelectorAll('source'); + if (!sources || !img) { + return null; + } + + const supportedSources = [...sources].filter((source) => { + const format = source.getAttribute('type'); + const media = source.getAttribute('media'); + return isImageFormatSupported(format) && (window.matchMedia(media).matches || !media); + }); + + if (supportedSources.length === 0) { + return img.src; + } + + return supportedSources[0].srcset; +} + +function setupAutopause(videoElement, player) { + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + player.play(); + } else { + player.pause(); + } + }); + }, { + threshold: [0.5], + }); + + observer.observe(videoElement); +} + +function setupPlayer(url, videoContainer, config) { + const videoElement = document.createElement('video'); + videoElement.classList.add('video-js'); + videoElement.id = `video-${Math.random().toString(36).substr(2, 9)}`; + if (config.playsinline || config.autoplay) { + videoElement.setAttribute('playsinline', ''); + } + + videoContainer.append(videoElement); + + const poster = config.poster ? getPosterImage(config.poster) : null; + const videojsConfig = { + ...config, + preload: poster && !config.autoplay ? 'none' : 'auto', + poster, + }; + + if (config.autoplay) { + videojsConfig.muted = true; + videojsConfig.loop = true; + videojsConfig.autoplay = true; + } + + // eslint-disable-next-line no-undef + const player = videojs(videoElement, videojsConfig); + player.src(url); + + if (config.hasCustomPlayButton) { + createPlayButton(videoContainer, player); + } + + player.ready(() => { + if (config.autoplay) { + setupAutopause(videoElement, player); + } + }); + + return player; +} + +async function decorateVideoPlayer(url, videoContainer, config) { + if (config.posterImage) { + videoContainer.append(config.posterImage); + } + + await waitForVideoJs(); + const player = setupPlayer(url, videoContainer, config); + player.on('loadeddata', () => { + const posterImage = videoContainer.querySelector('picture'); + if (posterImage) { + posterImage.style.display = 'none'; + } + }); +} + +async function decorateVideoCard(container, config) { + const videoContainer = document.createElement('div'); + videoContainer.classList.add('video-container'); + + const article = document.createElement('article'); + article.classList.add('video-card'); + article.append(videoContainer); + + if (config.title || config.description) { + const content = document.createElement('div'); + content.classList.add('video-card-content'); + + if (config.title) { + const title = document.createElement('h3'); + title.classList.add('video-card-title'); + title.textContent = config.title; + content.append(title); + } + + if (config.description) { + const description = document.createElement('p'); + description.classList.add('video-card-description'); + description.textContent = config.description; + content.append(description); + } + + article.append(content); + } + + container.append(article); + + decorateVideoPlayer(config.videoUrl, videoContainer, { + autoplay: config.isAutoPlay, + hasCustomPlayButton: true, + fill: true, + posterImage: config.posterImage, + }); +} + +async function decorateHeroBlock(block, config) { + const container = document.createElement('div'); + container.classList.add('video-hero'); + + const content = document.createElement('div'); + content.classList.add('video-hero-content'); + + if (config.title) { + const title = document.createElement('h1'); + title.classList.add('video-hero-title'); + title.textContent = config.title; + content.append(title); + } + + if (config.description) { + const description = document.createElement('p'); + description.classList.add('video-hero-description'); + description.textContent = config.description; + content.append(description); + } + + if (config.button) { + config.button.classList.add('video-hero-button'); + content.append(config.button); + } + + container.append(content); + + block.innerHTML = ''; + block.append(container); + + decorateVideoPlayer(config.videoUrl, container, { + autoplay: config.isAutoPlay, + hasCustomPlayButton: true, + fill: true, + posterImage: config.posterImage, + }); +} + +async function decorateVideoCards(block, config) { + const gridContainer = document.createElement('ul'); + gridContainer.classList.add('video-card-grid'); + + block.innerHTML = ''; + block.append(gridContainer); + + await Promise.all(config.cards.map(async (videoConfig) => { + const gridItem = document.createElement('li'); + gridItem.classList.add('video-card-grid-item'); + gridContainer.append(gridItem); + + await decorateVideoCard(gridItem, videoConfig); + })); +} + +function closeModal() { + const dialog = document.querySelector('.video-modal-dialog'); + dialog.querySelector('.video-container').innerHTML = ''; + + // eslint-disable-next-line no-use-before-define + window.removeEventListener('click', handleOutsideClick); + // eslint-disable-next-line no-use-before-define + window.removeEventListener('keydown', handleEscapeKey); + + dialog.close(); + document.body.style.overflow = ''; +} + +function handleOutsideClick(event) { + const modal = document.querySelector('.video-modal-dialog'); + if (event.target === modal) { + closeModal(); + } +} + +function handleEscapeKey(event) { + if (event.key === 'Escape') { + closeModal(); + } +} + +async function openModal(config) { + await loadVideoJs(); + + const dialog = document.querySelector('.video-modal-dialog'); + const container = dialog.querySelector('.video-container'); + setupPlayer(config.videoUrl, container, { + bigPlayButton: true, + fluid: true, + controls: true, + playsinline: true, + autoplay: true, + }); + + window.addEventListener('click', handleOutsideClick); + window.addEventListener('keydown', handleEscapeKey); + + dialog.showModal(); + document.body.style.overflow = 'hidden'; +} + +function createModal() { + const modal = document.createElement('dialog'); + modal.classList.add('video-modal-dialog'); + + const container = document.createElement('div'); + container.classList.add('video-modal'); + + const header = document.createElement('div'); + header.classList.add('video-modal-header'); + + const closeIcon = document.createElement('span'); + closeIcon.classList.add('icon'); + closeIcon.classList.add('icon-close'); + const closeBtn = document.createElement('button'); + closeBtn.setAttribute('aria-label', 'Close dialog'); + closeBtn.classList.add('video-modal-close'); + closeBtn.append(closeIcon); + closeBtn.addEventListener('click', () => { + closeModal(); + }); + + header.append(closeBtn); + decorateIcons(header); + + container.append(header); + + const content = document.createElement('div'); + content.classList.add('video-modal-content'); + + const videoContainer = document.createElement('div'); + videoContainer.classList.add('video-container'); + content.append(videoContainer); + + container.append(content); + modal.append(container); + document.body.append(modal); +} + +async function decorateVideoModal(block, config) { + const container = document.createElement('div'); + container.classList.add('video-component'); + + const posterImage = config.posterImage.cloneNode(true); + const playButton = document.createElement('button'); + playButton.setAttribute('aria-label', 'Play video'); + playButton.classList.add('video-play-button'); + + const playIcon = document.createElement('span'); + playIcon.classList.add('icon'); + playIcon.classList.add('icon-play'); + playButton.append(playIcon); + decorateIcons(playButton); + + playButton.addEventListener('click', async () => { + await openModal(config); + }); + + container.append(posterImage); + container.append(playButton); + + block.innerHTML = ''; + block.append(container); + + const hasVideoModal = document.querySelector('.video-modal-dialog'); + if (!hasVideoModal) { + createModal(); + } +} + +export default async function decorate(block) { + if (window.DELAYED_PHASE) { + loadVideoJs(); + } else { + const delayedPhaseHandler = async () => { + document.removeEventListener('delayed-phase', delayedPhaseHandler); + await loadVideoJs(); + }; + document.addEventListener('delayed-phase', delayedPhaseHandler); + } + + const config = parseConfig(block); + + if (config.type === 'hero') { + await decorateHeroBlock(block, config); + return; + } + + if (config.type === 'cards') { + await decorateVideoCards(block, config); + return; + } + + await decorateVideoModal(block, config); +} diff --git a/blocks/video/videojs/video-js.min.css b/blocks/video/videojs/video-js.min.css new file mode 100644 index 0000000000..e31bdcd99f --- /dev/null +++ b/blocks/video/videojs/video-js.min.css @@ -0,0 +1 @@ +.vjs-svg-icon{display:inline-block;background-repeat:no-repeat;background-position:center;fill:currentColor;height:1.8em;width:1.8em}.vjs-svg-icon:before{content:none!important}.vjs-control:focus .vjs-svg-icon,.vjs-svg-icon:hover{filter:drop-shadow(0 0 .25em #fff)}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,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) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10a"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10b"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10c"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-downloading{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-downloading:before{content:"\f10f"}.vjs-icon-file-download{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-file-download:before{content:"\f110"}.vjs-icon-file-download-done{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-file-download-done:before{content:"\f111"}.vjs-icon-file-download-off{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-file-download-off:before{content:"\f112"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f113"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f114"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f115"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f116"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f117"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f118"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f119"}.vjs-icon-repeat{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-repeat:before{content:"\f11a"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f11b"}.video-js .vjs-skip-backward-5 .vjs-icon-placeholder,.vjs-icon-replay-5{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-backward-5 .vjs-icon-placeholder:before,.vjs-icon-replay-5:before{content:"\f11c"}.video-js .vjs-skip-backward-10 .vjs-icon-placeholder,.vjs-icon-replay-10{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-backward-10 .vjs-icon-placeholder:before,.vjs-icon-replay-10:before{content:"\f11d"}.video-js .vjs-skip-backward-30 .vjs-icon-placeholder,.vjs-icon-replay-30{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-backward-30 .vjs-icon-placeholder:before,.vjs-icon-replay-30:before{content:"\f11e"}.video-js .vjs-skip-forward-5 .vjs-icon-placeholder,.vjs-icon-forward-5{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-forward-5 .vjs-icon-placeholder:before,.vjs-icon-forward-5:before{content:"\f11f"}.video-js .vjs-skip-forward-10 .vjs-icon-placeholder,.vjs-icon-forward-10{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-forward-10 .vjs-icon-placeholder:before,.vjs-icon-forward-10:before{content:"\f120"}.video-js .vjs-skip-forward-30 .vjs-icon-placeholder,.vjs-icon-forward-30{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-skip-forward-30 .vjs-icon-placeholder:before,.vjs-icon-forward-30:before{content:"\f121"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f122"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f123"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f124"}.vjs-icon-shuffle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-shuffle:before{content:"\f125"}.vjs-icon-cast{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cast:before{content:"\f126"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f127"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f128"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f129"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f12a"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f12b"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f12c"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f12d"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f12e"}.video-js{display:inline-block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-1-1,.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-9-16,.video-js.vjs-fluid{width:100%;max-width:100%}.video-js.vjs-1-1:not(.vjs-audio-only-mode),.video-js.vjs-16-9:not(.vjs-audio-only-mode),.video-js.vjs-4-3:not(.vjs-audio-only-mode),.video-js.vjs-9-16:not(.vjs-audio-only-mode),.video-js.vjs-fluid:not(.vjs-audio-only-mode){height:0}.video-js.vjs-16-9:not(.vjs-audio-only-mode){padding-top:56.25%}.video-js.vjs-4-3:not(.vjs-audio-only-mode){padding-top:75%}.video-js.vjs-9-16:not(.vjs-audio-only-mode){padding-top:177.7777777778%}.video-js.vjs-1-1:not(.vjs-audio-only-mode){padding-top:100%}.video-js.vjs-fill:not(.vjs-audio-only-mode){width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js.vjs-audio-only-mode .vjs-tech{display:none}body.vjs-full-window,body.vjs-pip-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen,body.vjs-pip-window .video-js{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen:not(.vjs-ios-native-fs),body.vjs-pip-window .video-js{width:100%!important;height:100%!important;padding-top:0!important;display:block}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-pip-container .vjs-pip-text{position:absolute;bottom:10%;font-size:2em;background-color:rgba(0,0,0,.7);padding:.5em;text-align:center;width:100%}.vjs-layout-small.vjs-pip-container .vjs-pip-text,.vjs-layout-tiny.vjs-pip-container .vjs-pip-text,.vjs-layout-x-small.vjs-pip-container .vjs-pip-text{bottom:0;font-size:1.4em}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1!important;visibility:visible!important}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:50%;left:50%;padding:0;margin-top:-.81666em;margin-left:-1.5em;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-button .vjs-svg-icon{width:1em;height:1em;position:absolute;top:50%;left:50%;line-height:1;transform:translate(-50%,-50%)}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause:not(.vjs-seeking,.vjs-scrubbing,.vjs-error) .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.video-js.vjs-spatial-navigation-enabled .vjs-button:focus{outline:.0625em solid #fff;box-shadow:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{display:flex;justify-content:center;list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.js-focus-visible .vjs-menu li.vjs-selected:hover .vjs-svg-icon,.vjs-menu li.vjs-selected .vjs-svg-icon,.vjs-menu li.vjs-selected:focus .vjs-svg-icon,.vjs-menu li.vjs-selected:hover .vjs-svg-icon{fill:#000}.js-focus-visible .vjs-menu :not(.vjs-selected):focus:not(.focus-visible),.video-js .vjs-menu :not(.vjs-selected):focus:not(:focus-visible){background:0 0}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-pip-window .vjs-menu-button-popup .vjs-menu{left:unset;right:1em}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js.vjs-spatial-navigation-enabled .vjs-control-bar{gap:1px}.video-js:not(.vjs-controls-disabled,.vjs-using-native-controls,.vjs-error) .vjs-control-bar.vjs-lock-showing{display:flex!important}.vjs-audio-only-mode .vjs-control-bar,.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;pointer-events:none;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio-only-mode.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar,.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible;pointer-events:auto}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.video-js .vjs-control.vjs-visible-text{width:auto;padding-left:1em;padding-right:1em}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.vjs-button>.vjs-icon-placeholder{display:block}.vjs-button>.vjs-svg-icon{display:inline-block}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js :not(.vjs-visible-text)>.vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;line-height:.35em;z-index:1}.vjs-svg-icons-enabled .vjs-play-progress:before{content:none!important}.vjs-play-progress .vjs-svg-icon{position:absolute;top:-.35em;right:-.4em;width:.9em;height:.9em;pointer-events:none;line-height:.15em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js.vjs-spatial-navigation-enabled .vjs-slider:focus{outline:.0625em solid #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em;z-index:1}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em;z-index:1}.vjs-svg-icons-enabled .vjs-volume-level:before{content:none}.vjs-volume-level .vjs-svg-icon{position:absolute;width:.9em;height:.9em;pointer-events:none;z-index:1}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{line-height:.35em;right:-.5em}.vjs-slider-horizontal .vjs-volume-level .vjs-svg-icon{right:-.3em;transform:translateY(-50%)}.vjs-slider-vertical .vjs-volume-level .vjs-svg-icon{top:-.55em;transform:translateX(-50%)}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.video-js .vjs-volume-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-volume-control:hover .vjs-progress-holder:focus .vjs-volume-tooltip,.video-js .vjs-volume-control:hover .vjs-volume-tooltip{display:block;font-size:1em;visibility:visible}.video-js .vjs-volume-vertical:hover .vjs-progress-holder:focus .vjs-volume-tooltip,.video-js .vjs-volume-vertical:hover .vjs-volume-tooltip{left:1em;top:-12px}.video-js .vjs-volume-control.disabled:hover .vjs-volume-tooltip{font-size:1em}.video-js .vjs-volume-control .vjs-mouse-display{display:none;position:absolute;width:100%;height:1px;background-color:#000;z-index:1}.video-js .vjs-volume-horizontal .vjs-mouse-display{width:1px;height:100%}.video-js .vjs-volume-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-volume-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.vjs-mouse-display .vjs-volume-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.vjs-poster{display:inline-block;vertical-align:middle;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster,.vjs-using-native-controls .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster,.vjs-has-started.vjs-audio-poster-mode .vjs-poster,.vjs-pip-container.vjs-has-started .vjs-poster{display:block}.vjs-poster img{width:100%;height:100%;object-fit:contain}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{align-items:center;cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-svg-icons-enabled .vjs-seek-to-live-control{line-height:0}.vjs-seek-to-live-control .vjs-svg-icon{width:1em;height:1em;pointer-events:none;fill:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-svg-icon{fill:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.video-js .vjs-current-time,.video-js .vjs-duration,.vjs-live .vjs-time-control,.vjs-live .vjs-time-divider{display:none}.vjs-time-divider{display:none;line-height:3em}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.vjs-error .vjs-text-track-display{display:none}.video-js.vjs-controls-disabled .vjs-text-track-display,.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-controls-disabled video::-webkit-media-text-track-display,.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js.vjs-force-center-align-cues .vjs-text-track-cue{text-align:center!important;width:80%!important}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js.vjs-audio-only-mode .vjs-picture-in-picture-control,.vjs-pip-window .vjs-picture-in-picture-control{display:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.video-js.vjs-audio-only-mode .vjs-fullscreen-control,.vjs-pip-window .vjs-fullscreen-control{display:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:.85;text-align:left;border:.6em solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:5em;height:5em;border-radius:50%;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:flex;justify-content:center;align-items:center;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-error .vjs-loading-spinner{display:none}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.video-js.vjs-audio-only-mode .vjs-captions-button{display:none}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js.vjs-audio-only-mode .vjs-descriptions-button{display:none}.vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-svg-icon{width:1.5em;height:1.5em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"\f10c";font-size:1.5em;line-height:inherit}.video-js.vjs-audio-only-mode .vjs-subs-caps-button{display:none}.video-js .vjs-audio-button+.vjs-menu .vjs-descriptions-menu-item .vjs-menu-item-text .vjs-icon-placeholder,.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-descriptions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before,.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" \f12e";font-size:1.5em;line-height:inherit}.video-js.vjs-layout-small .vjs-current-time,.video-js.vjs-layout-small .vjs-duration,.video-js.vjs-layout-small .vjs-playback-rate,.video-js.vjs-layout-small .vjs-remaining-time,.video-js.vjs-layout-small .vjs-time-divider,.video-js.vjs-layout-small .vjs-volume-control,.video-js.vjs-layout-tiny .vjs-current-time,.video-js.vjs-layout-tiny .vjs-duration,.video-js.vjs-layout-tiny .vjs-playback-rate,.video-js.vjs-layout-tiny .vjs-remaining-time,.video-js.vjs-layout-tiny .vjs-time-divider,.video-js.vjs-layout-tiny .vjs-volume-control,.video-js.vjs-layout-x-small .vjs-current-time,.video-js.vjs-layout-x-small .vjs-duration,.video-js.vjs-layout-x-small .vjs-playback-rate,.video-js.vjs-layout-x-small .vjs-remaining-time,.video-js.vjs-layout-x-small .vjs-time-divider,.video-js.vjs-layout-x-small .vjs-volume-control{display:none}.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js.vjs-layout-tiny .vjs-progress-control,.video-js.vjs-layout-x-small .vjs-progress-control{display:none}.video-js.vjs-layout-x-small .vjs-custom-control-spacer{flex:auto;display:block}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-spatial-navigation-enabled .vjs-modal-dialog.vjs-text-track-settings{height:80%}.vjs-error .vjs-text-track-settings{display:none}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-text-track-settings select{font-size:inherit}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:10px;border:none}.vjs-text-track-settings fieldset span{display:inline-block;padding:0 .6em .8em}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;font-weight:700;font-size:1.2em}.vjs-text-track-settings .vjs-label{margin:0 .5em .5em 0}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}.vjs-title-bar{background:rgba(0,0,0,.9);background:linear-gradient(180deg,rgba(0,0,0,.9) 0,rgba(0,0,0,.7) 60%,rgba(0,0,0,0) 100%);font-size:1.2em;line-height:1.5;transition:opacity .1s;padding:.666em 1.333em 4em;pointer-events:none;position:absolute;top:0;width:100%}.vjs-error .vjs-title-bar{display:none}.vjs-title-bar-description,.vjs-title-bar-title{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vjs-title-bar-title{font-weight:700;margin-bottom:.333em}.vjs-playing.vjs-user-inactive .vjs-title-bar{opacity:0;transition:opacity 1s}.video-js .vjs-skip-forward-5{cursor:pointer}.video-js .vjs-skip-forward-10{cursor:pointer}.video-js .vjs-skip-forward-30{cursor:pointer}.video-js .vjs-skip-backward-5{cursor:pointer}.video-js .vjs-skip-backward-10{cursor:pointer}.video-js .vjs-skip-backward-30{cursor:pointer}.video-js .vjs-transient-button{position:absolute;height:3em;display:flex;align-items:center;justify-content:center;background-color:rgba(50,50,50,.5);cursor:pointer;opacity:1;transition:opacity 1s}.video-js:not(.vjs-has-started) .vjs-transient-button{display:none}.video-js.not-hover .vjs-transient-button:not(.force-display),.video-js.vjs-user-inactive .vjs-transient-button:not(.force-display){opacity:0}.video-js .vjs-transient-button span{padding:0 .5em}.video-js .vjs-transient-button.vjs-left{left:1em}.video-js .vjs-transient-button.vjs-right{right:1em}.video-js .vjs-transient-button.vjs-top{top:1em}.video-js .vjs-transient-button.vjs-near-top{top:4em}.video-js .vjs-transient-button.vjs-bottom{bottom:4em}.video-js .vjs-transient-button:hover{background-color:rgba(50,50,50,.9)}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0}.video-js :focus:not(:focus-visible){outline:0} \ No newline at end of file diff --git a/blocks/video/videojs/video.min.js b/blocks/video/videojs/video.min.js new file mode 100644 index 0000000000..a1d15bd657 --- /dev/null +++ b/blocks/video/videojs/video.min.js @@ -0,0 +1,53 @@ +/** + * @license + * Video.js 8.17.3