diff --git a/blocks/embed/embed.css b/blocks/embed/embed.css index 1b2f7e3e..15271bfa 100644 --- a/blocks/embed/embed.css +++ b/blocks/embed/embed.css @@ -48,17 +48,6 @@ text-decoration: underline; } -.embed .cookie-message__button-container { - margin-top: 16px; - display: flex; - justify-content: center; - gap: 16px; -} - -.embed.single-video .embed-video-element { - border-radius: var(--border-radius); -} - @media screen and (min-width: 768px) { .embed-video { width: 726px; @@ -69,18 +58,6 @@ } } -@media screen and (min-width: 1200px) { - .embed .cookie-message__title { - font-size: var(--f-heading-4-font-size); - line-height: var(--f-heading-4-line-height); - } - - .embed .cookie-message__text { - font-size: var(--f-body-2-font-size); - line-height: var(--f-body-2-line-height); - } -} - @media screen and (min-width: 1300px) { .embed-video { width: 1170px; diff --git a/blocks/embed/embed.js b/blocks/embed/embed.js index 09117ed9..c5c86a54 100644 --- a/blocks/embed/embed.js +++ b/blocks/embed/embed.js @@ -1,12 +1,11 @@ -import { createElement, getTextLabel, isExternalVideoAllowed } from '../../scripts/common.js'; import { - selectVideoLink, addPlayIcon, showVideoModal, isLowResolutionVideoUrl, + selectVideoLink, addPlayIcon, + showVideoModal, isLowResolutionVideoUrl, createLowResolutionBanner, createIframe, } from '../../scripts/video-helper.js'; export default function decorate(block) { const isAutoplay = block.classList.contains('autoplay'); - const isSingleVideo = block.classList.contains('single-video'); const isLoopedVideo = block.classList.contains('loop'); const isFullWidth = block.classList.contains('full-width'); const hideLowResolutionBanner = block.classList.contains('no-banner'); @@ -16,7 +15,6 @@ export default function decorate(block) { videoWrapper.classList.add('embed-video'); const preferredType = (() => { - if (isSingleVideo) return 'singleVideo'; if (isFullWidth) return 'local'; return 'auto'; })(); @@ -26,34 +24,6 @@ export default function decorate(block) { const video = document.createElement('video'); const source = document.createElement('source'); - if (isSingleVideo && !isExternalVideoAllowed()) { - const img = block.querySelector('picture img'); - block.innerHTML = ''; - - const cookieMsgConatiner = createElement('div', { - classes: 'cookie-message', - }); - cookieMsgConatiner.style.background = `linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, rgba(0, 0, 0, 0.80) 100%), url(${img.src}) 100% center / cover no-repeat`; - - const cookieMessage = document.createRange().createContextualFragment(` - - - - `); - - cookieMsgConatiner.append(cookieMessage); - block.append(cookieMsgConatiner); - - block.querySelector('.cookie-message__button-container .primary')?.addEventListener('click', () => { - document.cookie = 'isSingleVideo=true'; - }); - - return; - } - if (!selectedLink) { block.innerHTML = ''; /* eslint-disable-next-line no-console */ diff --git a/blocks/v2-livestream-embed/v2-livestream-embed.css b/blocks/v2-livestream-embed/v2-livestream-embed.css new file mode 100644 index 00000000..e31a880b --- /dev/null +++ b/blocks/v2-livestream-embed/v2-livestream-embed.css @@ -0,0 +1,63 @@ +.v2-livestream-embed { + border-radius: var(--border-radius); + aspect-ratio: 16/9; + width: 100%; +} + +.v2-livestream-embed iframe { + display: block; +} + +.v2-livestream-embed .cookie-message { + aspect-ratio: 16/9; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; +} + +.v2-livestream-embed .cookie-message__title, +.v2-livestream-embed .cookie-message__text { + max-width: var(--text-block-max-width); + margin: 0 auto; + text-align: center; +} + +.v2-livestream-embed .cookie-message__title { + font: var(--f-heading-5-font-size)/var(--f-heading-5-line-height) var(--ff-volvo-novum-medium); + letter-spacing: var(--f-heading-5-letter-spacing); +} + +.v2-livestream-embed .cookie-message__text { + font: var(--f-body-font-size)/var(--f-body-line-height) var(--font-family-body); +} + +.v2-livestream-embed .cookie-message__text a { + color: inherit; + text-decoration: underline; +} + +.v2-livestream-embed .cookie-message__text a:hover { + color: var(--c-grey-300); +} + +.v2-livestream-embed .cookie-message__button-container { + margin-top: 16px; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 16px; +} + +@media screen and (min-width: 1200px) { + .v2-livestream-embed .cookie-message__title { + font-size: var(--f-heading-4-font-size); + line-height: var(--f-heading-4-line-height); + } + + .v2-livestream-embed .cookie-message__text { + font-size: var(--f-body-2-font-size); + line-height: var(--f-body-2-line-height); + } +} diff --git a/blocks/v2-livestream-embed/v2-livestream-embed.js b/blocks/v2-livestream-embed/v2-livestream-embed.js new file mode 100644 index 00000000..13835558 --- /dev/null +++ b/blocks/v2-livestream-embed/v2-livestream-embed.js @@ -0,0 +1,113 @@ +/* eslint-disable no-console */ +/* eslint-disable no-unused-vars */ +/* eslint-disable max-len */ +import { loadScript } from '../../scripts/lib-franklin.js'; +import { createElement, getTextLabel, isExternalVideoAllowed } from '../../scripts/common.js'; +import { updateCookieValue } from '../../scripts/delayed.js'; +import { hideModal } from '../../common/modal/modal.js'; + +let player; + +function onPlayerReady(event) { + console.info('Event: onPlayerReady'); + event.target.playVideo(); +} + +function onPlayerError(event) { + console.warn('Event: onPlayerError'); + console.warn(event.data); +} + +function onPlayerAutoplayBlocked(event) { + console.warn('Event: onPlayerAutoplayBlocked'); + console.warn(event.data); +} + +export function playVideo() { + if (player && player.playVideo) { + player.playVideo(); + } +} + +export default function decorate(block) { + loadScript('https://www.youtube.com/iframe_api'); + + let [videoLink] = block.querySelectorAll('a'); + const [, videoId] = videoLink.getAttribute('href').split('/embed/'); + const [videoCode] = videoId.split('?'); + videoLink = videoCode; + + console.info(`video id: ${videoLink}`); + + if (!videoLink) { + block.innerHTML = ''; + /* eslint-disable-next-line no-console */ + console.warn('V2 Livestream Embed block: There is no video link. Please check the provided URL.'); + return; + } + + // eslint-disable-next-line func-names + window.onYouTubeIframeAPIReady = function () { + setTimeout(() => { + // eslint-disable-next-line no-undef + player = new YT.Player('livestream', { + events: { + onReady: onPlayerReady, + onError: onPlayerError, + onAutoplayBlocked: onPlayerAutoplayBlocked, + }, + }); + }, 3000); + }; + + if (!isExternalVideoAllowed()) { + const img = block.querySelector('picture img'); + block.innerHTML = ''; + + const cookieMsgContainer = createElement('div', { + classes: 'cookie-message', + }); + cookieMsgContainer.style.background = `linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, rgba(0, 0, 0, 0.80) 100%), url(${img.src}) center / cover no-repeat`; + + const cookieMessage = document.createRange().createContextualFragment(` + + ${getTextLabel('single video message text')} + + `); + + cookieMsgContainer.append(cookieMessage); + block.append(cookieMsgContainer); + + block.querySelector('.cookie-message__button-container .primary')?.addEventListener('click', () => { + const domain = 'localhost'; + const path = '/'; // assuming root path + const expirationDate = new Date(); + expirationDate.setFullYear(expirationDate.getFullYear() + 1); // 1 year from now + const sameSite = 'Lax'; + + console.log('updatecookie'); + + updateCookieValue('OptanonConsent=', 'C0005:0', 'C0005:1', domain, path, expirationDate, sameSite); + }); + + block.querySelector('.cookie-message__button-container .secondary')?.addEventListener('click', () => { + hideModal(); + }); + + return; + } + + const iframeYT = document.createRange().createContextualFragment(` + + `); + + block.innerHTML = ''; + + block.append(...iframeYT.childNodes); +} diff --git a/common/modal/modal.css b/common/modal/modal.css index b3783b4a..07f40484 100644 --- a/common/modal/modal.css +++ b/common/modal/modal.css @@ -236,3 +236,20 @@ width: 100%; } } + +.modal-reveal { + display: flex; + flex-direction: column; + justify-content: center; +} + +/* stylelint-disable-next-line no-descending-specificity */ +.modal-reveal .modal-content { + height: auto; + aspect-ratio: auto; +} + +.modal-reveal .section > div { + padding-top: 0; + padding-bottom: 0; +} diff --git a/common/modal/modal.js b/common/modal/modal.js index a4d0a4cb..23343571 100644 --- a/common/modal/modal.js +++ b/common/modal/modal.js @@ -35,8 +35,10 @@ const createModal = () => { modalBackground.setAttribute('role', 'dialog'); modalBackground.addEventListener('click', () => { - // eslint-disable-next-line no-use-before-define - hideModal(); + if (!modalBackground.classList.contains('modal-reveal')) { + // eslint-disable-next-line no-use-before-define + hideModal(); + } }); const keyDownAction = (event) => { diff --git a/placeholder.json b/placeholder.json index 408136cb..5000b7f2 100644 --- a/placeholder.json +++ b/placeholder.json @@ -233,15 +233,15 @@ }, { "Key": "single video message text", - "Text": "Our media viewer uses social media cookies and/or similar technologies set by third-party services, as outlined in our cookie policy. Use the “Okay” button or close this notice to consent and view hi-res media. Select “Deny” to view in low resolution." + "Text": "

Our media viewer uses social media cookies and/or similar technologies set by third-party services, as outlined in our Cookie Notice. We and our digital partners use cookies to improve your browsing experience, save your preferences and provide us with information on how you use our website.

You can click “Accept All Cookies” to view the reveal and to agree to the storing of cookies on your device and to our use of cookies. You can also configure or reject cookies by clicking on “Cookie Settings” or “Reject All.” Please note that rejecting cookies means that you will not be able to view the reveal. Please also note that selecting “Reject All” still implies that necessary cookies will remain.

" }, { "Key": "single video message button", - "Text": "Okay" + "Text": "Accept All Cookies" }, { "Key": "single video message button deny", - "Text": "Deny" + "Text": "Reject All" } ], ":type": "sheet" diff --git a/scripts/delayed.js b/scripts/delayed.js index 40b3fd4f..992f946f 100644 --- a/scripts/delayed.js +++ b/scripts/delayed.js @@ -1,3 +1,4 @@ +// eslint-disable no-console // eslint-disable-next-line import/no-cycle import { loadScript, sampleRUM } from './lib-franklin.js'; @@ -14,6 +15,40 @@ const cookieSetting = decodeURIComponent(document.cookie.split(';') const isPerformanceAllowed = cookieSetting.includes(COOKIES.performance); const isSocialAllowed = cookieSetting.includes(COOKIES.social); +export function updateCookieValue(cookieName, oldValue, newValue, domain, path, expires, sameSite) { + let cookies = decodeURIComponent(document.cookie).split(';'); + console.info(cookies); + + for (let i = 0; i < cookies.length; i++) { + let cookie = cookies[i].trim(); + if (cookie.startsWith(cookieName)) { + let cookieValue = cookie.substring(cookieName.length); + console.info(cookieValue); + if (cookieValue.includes(oldValue)) { + console.info(oldValue); + let updatedValue = encodeURIComponent(cookieValue.replace(oldValue, newValue)); + console.info(updatedValue); + let updatedCookie = cookieName + updatedValue; + console.info(updatedCookie); + if (domain) { + updatedCookie += `; domain=${domain}`; + } + if (path) { + updatedCookie += `; path=${path}`; + } + if (expires) { + updatedCookie += `; expires=${expires.toUTCString()}`; + } + if (sameSite) { + updatedCookie += `; SameSite=${sameSite}`; + } + document.cookie = updatedCookie; + } + break; + } + } +} + if (isPerformanceAllowed) { loadGoogleTagManager(); loadHotjar(); diff --git a/scripts/video-helper.js b/scripts/video-helper.js index 4f3116b6..ceb55272 100644 --- a/scripts/video-helper.js +++ b/scripts/video-helper.js @@ -365,3 +365,10 @@ export const addMuteControls = (section) => { controls.addEventListener('click', () => toggleMute(video)); }; + +export function loadYouTubeIframeAPI() { + const tag = document.createElement('script'); + tag.src = 'https://www.youtube.com/iframe_api'; + const firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); +} diff --git a/styles/styles.css b/styles/styles.css index c72aa365..a3095c08 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -891,7 +891,7 @@ a.button.text-link-with-video::after { margin: 0; } -.redesign-v2 .button.secondary { +.redesign-v2 .low-resolution-banner .button.secondary { margin-left: auto; }