Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to display Digital Reveal Cookie management message in Modal video #313 #318

Merged
merged 7 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion blocks/embed/embed.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,43 @@
.embed-video-element {
aspect-ratio: 16/9;
width: 100%;
display: block;
}

.embed .video-icon-wrapper {
pointer-events: none;
}

.embed .cookie-message {
aspect-ratio: 16/9;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
}

.embed .cookie-message__title,
.embed .cookie-message__text {
max-width: var(--text-block-max-width);
margin: 0 auto;
text-align: center;
}

.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);
}

.embed .cookie-message__text {
font: var(--f-body-font-size)/var(--f-body-line-height) var(--font-family-body);
}

.embed .cookie-message__text a {
color: inherit;
text-decoration: underline;
}

@media screen and (min-width: 768px) {
.embed-video {
width: 726px;
Expand All @@ -35,4 +66,4 @@
.embed.embed-full-width .embed-video {
width: 100%;
}
}
}
10 changes: 8 additions & 2 deletions blocks/embed/embed.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
selectVideoLink, addPlayIcon, showVideoModal, isLowResolutionVideoUrl,
selectVideoLink, addPlayIcon,
showVideoModal, isLowResolutionVideoUrl,
createLowResolutionBanner, createIframe,
} from '../../scripts/video-helper.js';

Expand All @@ -13,8 +14,13 @@ export default function decorate(block) {
block.classList.remove('loop', 'autoplay', 'full-width');
videoWrapper.classList.add('embed-video');

const preferredType = (() => {
if (isFullWidth) return 'local';
return 'auto';
})();

const links = block.querySelectorAll('a');
const selectedLink = selectVideoLink(links, isFullWidth ? 'local' : 'auto');
const selectedLink = selectVideoLink(links, preferredType);
const video = document.createElement('video');
const source = document.createElement('source');

Expand Down
63 changes: 63 additions & 0 deletions blocks/v2-livestream-embed/v2-livestream-embed.css
Original file line number Diff line number Diff line change
@@ -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);
}
}
113 changes: 113 additions & 0 deletions blocks/v2-livestream-embed/v2-livestream-embed.js
Original file line number Diff line number Diff line change
@@ -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(`
<h3 class="cookie-message__title">${getTextLabel('single video message title')}</h3>
${getTextLabel('single video message text')}
<div class="cookie-message__button-container">
<button class="primary dark">${getTextLabel('single video message button')}</button>
<button class="button secondary dark">${getTextLabel('single video message button deny')}</button>
</div>
`);

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(`
<iframe class="v2-livestream-embed" id="livestream"
frameborder="0" allowfullscreen="" allow="autoplay"
src="https://www.youtube.com/embed/${videoLink}?color=white&amp;rel=0&amp;playsinline=1&amp;enablejsapi=1&amp;autoplay=1">
</iframe>
`);

block.innerHTML = '';

block.append(...iframeYT.childNodes);
}
17 changes: 17 additions & 0 deletions common/modal/modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 4 additions & 2 deletions common/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
16 changes: 14 additions & 2 deletions placeholder.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,20 @@
"Text": "Model year"
},
{
"Key": "go to top",
"Text": "Go to the top of the page"
"Key": "single video message title",
"Text": "Enable cookies to view the reveal in high resolution?"
},
{
"Key": "single video message text",
"Text": "<p class=\"cookie-message__text\">Our media viewer uses social media cookies and/or similar technologies set by third-party services, as outlined in our <a href=\"/cookies/\">Cookie Notice</a>. 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.</p><p class=\"cookie-message__text\">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.</p>"
},
{
"Key": "single video message button",
"Text": "Accept All Cookies"
},
{
"Key": "single video message button deny",
"Text": "Reject All"
}
],
":type": "sheet"
Expand Down
8 changes: 6 additions & 2 deletions scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,17 @@ export const slugify = (text) => (
* Check if one trust group is checked.
* @param {String} groupName the one trust croup like: C0002
*/
export function checkOneTruckGroup(groupName) {
export function checkOneTrustGroup(groupName) {
const oneTrustCookie = decodeURIComponent(document.cookie.split(';').find((cookie) => cookie.trim().startsWith('OptanonConsent=')));
return oneTrustCookie.includes(`${groupName}:1`);
}

export function isEloquaFormAllowed() {
return checkOneTruckGroup('C0004');
return checkOneTrustGroup('C0004');
}

export function isExternalVideoAllowed() {
return checkOneTrustGroup('C0005');
}

/*
Expand Down
42 changes: 41 additions & 1 deletion scripts/delayed.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable no-console
// eslint-disable-next-line import/no-cycle
import { loadScript, sampleRUM } from './lib-franklin.js';

Expand All @@ -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();
Expand Down Expand Up @@ -57,9 +92,14 @@ if (!window.location.pathname.includes('srcdoc')
return s1 === s2;
}

const isSingleVideo = document.cookie.split('; ').reduce((r, v) => {
const parts = v.split('=');
return parts[0] === 'isSingleVideo' ? decodeURIComponent(parts[1]) : r;
}, '');

window.OneTrust.OnConsentChanged(() => {
// reloading the page only when the active group has changed
if (!isSameGroups(currentOnetrustActiveGroups, window.OnetrustActiveGroups)) {
if (!isSameGroups(currentOnetrustActiveGroups, window.OnetrustActiveGroups) && isSingleVideo !== 'true') {
window.location.reload();
}
});
Expand Down
Loading