From a0e3d531c99d2be5ccec27dfe5880018b7513559 Mon Sep 17 00:00:00 2001 From: Karel-Jan Van Haute Date: Tue, 17 Sep 2024 18:09:56 +0200 Subject: [PATCH] Block youtube video's if cookies are not set Fixes #309 --- .../js/components/videoToggle.component.ts | 161 ++++++++---------- .../_snippet/_content/_blocks/_textVideo.twig | 18 +- .../_snippet/_content/_blocks/_video.twig | 18 +- 3 files changed, 103 insertions(+), 94 deletions(-) diff --git a/tailoff/js/components/videoToggle.component.ts b/tailoff/js/components/videoToggle.component.ts index 2966f477..014ace90 100644 --- a/tailoff/js/components/videoToggle.component.ts +++ b/tailoff/js/components/videoToggle.component.ts @@ -1,23 +1,40 @@ -import { DOMHelper } from "../utils/domHelper"; +import { Ajax } from '../utils/ajax'; +import { Cookies } from '../utils/cookies'; export class VideoToggleComponent { constructor() { - const triggers = document.querySelectorAll("button[data-s-video-toggle]"); + const triggers = document.querySelectorAll('button[data-s-video-toggle]'); Array.from(triggers).forEach((trigger, index) => { new VideoToggle(trigger as HTMLButtonElement, index); }); + + const consent = Cookies.getCookie('__cookie_consent'); + if (consent !== 'true' && consent !== '2') { + window.addEventListener('cookie-closed', () => { + const newConsent = Cookies.getCookie('__cookie_consent'); + if (newConsent === 'true' || newConsent === '2') { + triggers.forEach((trigger: HTMLButtonElement) => { + trigger.disabled = false; + }); + const videoBlockers = document.querySelectorAll('[data-video-consent-blocker]'); + Array.from(videoBlockers).forEach((blocker: HTMLElement) => { + blocker.remove(); + }); + } + }); + } } } class VideoToggle { private options = { - url: "", + url: '', container: null, - aspectRatio: "auto", + aspectRatio: 'auto', hideTrigger: true, showCloseButton: true, - hideClass: "hidden", - toggleContent: "close", + hideClass: 'hidden', + toggleContent: 'close', }; private trigger: HTMLButtonElement; @@ -25,90 +42,70 @@ class VideoToggle { private videoIFrame: HTMLIFrameElement; private videoCloseButton: HTMLButtonElement; private videoOpen = false; - private openContent = ""; + private openContent = ''; constructor(trigger: HTMLButtonElement, index: number = 0) { this.trigger = trigger; - this.options.url = trigger.getAttribute("data-s-video-toggle") as string; - this.options.container = trigger.hasAttribute( - "data-s-video-toggle-container" - ) - ? document.querySelector( - trigger.getAttribute("data-s-video-toggle-container") - ) + this.options.url = trigger.getAttribute('data-s-video-toggle') as string; + this.options.container = trigger.hasAttribute('data-s-video-toggle-container') + ? document.querySelector(trigger.getAttribute('data-s-video-toggle-container')) : trigger.parentElement; - this.options.aspectRatio = trigger.hasAttribute( - "data-s-video-toggle-aspect-ratio" - ) - ? (trigger.getAttribute("data-s-video-toggle-aspect-ratio") as string) + this.options.aspectRatio = trigger.hasAttribute('data-s-video-toggle-aspect-ratio') + ? (trigger.getAttribute('data-s-video-toggle-aspect-ratio') as string) : this.options.aspectRatio; - this.options.showCloseButton = trigger.hasAttribute( - "data-s-video-toggle-show-close-button" - ) - ? (trigger.getAttribute( - "data-s-video-toggle-show-close-button" - ) as string) === "true" + this.options.showCloseButton = trigger.hasAttribute('data-s-video-toggle-show-close-button') + ? (trigger.getAttribute('data-s-video-toggle-show-close-button') as string) === 'true' : this.options.showCloseButton; - this.options.hideTrigger = trigger.hasAttribute( - "data-s-video-toggle-hide-trigger" - ) - ? (trigger.getAttribute("data-s-video-toggle-hide-trigger") as string) === - "true" + this.options.hideTrigger = trigger.hasAttribute('data-s-video-toggle-hide-trigger') + ? (trigger.getAttribute('data-s-video-toggle-hide-trigger') as string) === 'true' : this.options.hideTrigger; - this.options.hideClass = trigger.hasAttribute( - "data-s-video-toggle-hide-class" - ) - ? (trigger.getAttribute("data-s-video-toggle-hide-class") as string) + this.options.hideClass = trigger.hasAttribute('data-s-video-toggle-hide-class') + ? (trigger.getAttribute('data-s-video-toggle-hide-class') as string) : this.options.hideClass; - this.options.toggleContent = trigger.hasAttribute( - "data-s-video-toggle-toggle-content" - ) - ? (trigger.getAttribute("data-s-video-toggle-toggle-content") as string) + this.options.toggleContent = trigger.hasAttribute('data-s-video-toggle-toggle-content') + ? (trigger.getAttribute('data-s-video-toggle-toggle-content') as string) : this.options.toggleContent; - this.videoContent = document.createElement("div"); - this.videoContent.classList.add("video-toggle__content"); + this.videoContent = document.createElement('div'); + this.videoContent.classList.add('video-toggle__content'); this.videoContent.classList.add(this.options.hideClass); - this.videoContent.id = "videoToggleContent" + index; + this.videoContent.id = 'videoToggleContent' + index; - this.videoIFrame = document.createElement("iframe"); - this.videoIFrame.classList.add("video-toggle__iframe"); - this.videoIFrame.setAttribute("title", "Video embed"); + this.videoIFrame = document.createElement('iframe'); + this.videoIFrame.classList.add('video-toggle__iframe'); + this.videoIFrame.setAttribute('title', 'Video embed'); this.videoIFrame.setAttribute( - "allow", - "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" + 'allow', + 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' ); - this.videoIFrame.setAttribute("allowfullscreen", ""); - this.videoIFrame.setAttribute("width", "100%"); - this.videoIFrame.setAttribute("height", "100%"); + this.videoIFrame.setAttribute('allowfullscreen', ''); + this.videoIFrame.setAttribute('width', '100%'); + this.videoIFrame.setAttribute('height', '100%'); this.videoContent.appendChild(this.videoIFrame); this.options.container.appendChild(this.videoContent); - this.options.container.classList.add("video-toggle__container"); + this.options.container.classList.add('video-toggle__container'); if (this.options.showCloseButton) { - this.videoCloseButton = document.createElement("button"); - this.videoCloseButton.classList.add("video-toggle__close"); + this.videoCloseButton = document.createElement('button'); + this.videoCloseButton.classList.add('video-toggle__close'); this.videoCloseButton.classList.add(this.options.hideClass); - this.videoCloseButton.setAttribute("aria-label", "Close video"); - this.videoCloseButton.setAttribute("title", "Close video"); - this.videoCloseButton.addEventListener( - "click", - this.closeVideo.bind(this) - ); + this.videoCloseButton.setAttribute('aria-label', 'Close video'); + this.videoCloseButton.setAttribute('title', 'Close video'); + this.videoCloseButton.addEventListener('click', this.closeVideo.bind(this)); this.options.container.appendChild(this.videoCloseButton); } - trigger.setAttribute("aria-expanded", "false"); - trigger.setAttribute("aria-controls", "videoToggleContent" + index); + trigger.setAttribute('aria-expanded', 'false'); + trigger.setAttribute('aria-controls', 'videoToggleContent' + index); - trigger.addEventListener("click", this.toggleVideo.bind(this)); + trigger.addEventListener('click', this.toggleVideo.bind(this)); } private toggleVideo(e: Event) { @@ -120,15 +117,9 @@ class VideoToggle { } private clearVideoContainer() { - const videocloseButtons = this.options.container.querySelectorAll( - ".video-toggle__close" - ); - const videoContentBlocks = this.options.container.querySelectorAll( - ".video-toggle__content" - ); - const videoIframes = this.options.container.querySelectorAll( - ".video-toggle__iframe" - ); + const videocloseButtons = this.options.container.querySelectorAll('.video-toggle__close'); + const videoContentBlocks = this.options.container.querySelectorAll('.video-toggle__content'); + const videoIframes = this.options.container.querySelectorAll('.video-toggle__iframe'); Array.from(videocloseButtons).forEach((button: HTMLElement) => { button.classList.add(this.options.hideClass); @@ -137,15 +128,15 @@ class VideoToggle { block.classList.add(this.options.hideClass); }); Array.from(videoIframes).forEach((iframe: HTMLIFrameElement) => { - iframe.setAttribute("src", ""); + iframe.setAttribute('src', ''); }); } private openVideo(e: Event) { this.clearVideoContainer(); - this.trigger.setAttribute("aria-expanded", "true"); + this.trigger.setAttribute('aria-expanded', 'true'); this.videoContent.classList.remove(this.options.hideClass); - this.videoIFrame.setAttribute("src", this.options.url + "?autoplay=1"); + this.videoIFrame.setAttribute('src', this.options.url + '?autoplay=1'); if (this.options.showCloseButton) { this.videoCloseButton.classList.remove(this.options.hideClass); } @@ -155,25 +146,23 @@ class VideoToggle { this.openContent = this.trigger.innerHTML; this.trigger.innerHTML = this.options.toggleContent; } - if (this.options.aspectRatio !== "auto") { - const aspectRatio = this.options.aspectRatio.split(":"); + if (this.options.aspectRatio !== 'auto') { + const aspectRatio = this.options.aspectRatio.split(':'); const width = parseInt(aspectRatio[0]); const height = parseInt(aspectRatio[1]); const newHeight = (this.options.container.offsetWidth * height) / width; - this.options.container.style.height = newHeight + "px"; + this.options.container.style.height = newHeight + 'px'; } this.videoOpen = true; - document.dispatchEvent( - new CustomEvent("s:video:open", { detail: this.videoContent }) - ); + document.dispatchEvent(new CustomEvent('s:video:open', { detail: this.videoContent })); } private closeVideo(e: Event) { - this.trigger.setAttribute("aria-expanded", "false"); + this.trigger.setAttribute('aria-expanded', 'false'); this.videoContent.classList.add(this.options.hideClass); - this.videoIFrame.setAttribute("src", ""); + this.videoIFrame.setAttribute('src', ''); if (this.options.showCloseButton) { this.videoCloseButton.classList.add(this.options.hideClass); } @@ -182,19 +171,15 @@ class VideoToggle { } else { this.trigger.innerHTML = this.openContent; } - if (this.options.aspectRatio !== "auto") { - this.options.container.style.height = ""; + if (this.options.aspectRatio !== 'auto') { + this.options.container.style.height = ''; } this.videoOpen = false; - document.dispatchEvent( - new CustomEvent("s:video:close", { detail: this.videoContent }) - ); + document.dispatchEvent(new CustomEvent('s:video:close', { detail: this.videoContent })); - const containerToggleButton = this.options.container.querySelector( - "[data-s-video-toggle]" - ); + const containerToggleButton = this.options.container.querySelector('[data-s-video-toggle]'); if (containerToggleButton) { containerToggleButton.classList.remove(this.options.hideClass); diff --git a/templates/_site/_snippet/_content/_blocks/_textVideo.twig b/templates/_site/_snippet/_content/_blocks/_textVideo.twig index 37eb2abe..16e87b76 100644 --- a/templates/_site/_snippet/_content/_blocks/_textVideo.twig +++ b/templates/_site/_snippet/_content/_blocks/_textVideo.twig @@ -3,11 +3,12 @@
{% if block.video|length %} + {% set consent = craft.app.request.rawCookies.value('__cookie_consent') %} {% set embed = craft.videoparser.parse(block.video) %} {% if embed %}
-
+
{% set image = block.placeholderImage.collect().first() %} {% if image %} {% set optimizedImage = image.optimizedTextImage %} @@ -36,11 +37,22 @@ + {% if consent != "true" and consent != "2" %} +
+

{{ 'Cookie consent required'|t }}

+

{{ 'This video can only be viewed after accepting cookies'|t }}

+
+ + {{ "Or view this video on "|t}}{{embed.type}} +
+
+ {% endif %}
{% if block.videoCaption|length %}
diff --git a/templates/_site/_snippet/_content/_blocks/_video.twig b/templates/_site/_snippet/_content/_blocks/_video.twig index 5aae8c48..5bbcaad3 100644 --- a/templates/_site/_snippet/_content/_blocks/_video.twig +++ b/templates/_site/_snippet/_content/_blocks/_video.twig @@ -1,9 +1,10 @@ {% if block.video|length %}
{% set embed = craft.videoparser.parse(block.video) %} + {% set consent = craft.app.request.rawCookies.value('__cookie_consent') %} {% if embed %} -
+
{% set image = block.placeholderImage.collect().first() %} {% if image %} {% set optimizedImage = image.optimizedTextImage %} @@ -32,11 +33,22 @@ + {% if consent != "true" and consent != "2" %} +
+

{{ 'Cookie consent required'|t }}

+

{{ 'This video can only be viewed after accepting cookies'|t }}

+
+ + {{ "Or view this video on "|t}}{{embed.type}} +
+
+ {% endif %}
{% endif %}