src/cmp/cmp.js
import { cpexLog, cpexWarn, cpexError, addTCFStub, loadScript, addElement, setCookie } from '../utils.js'
import { PayOkay } from './pay.js'
/**
* Consent Management Platform (banner and TCF API), based on iab specs
*/
export default class CMP {
constructor (main) {
this.main = main
this.loaded = false
this.settings = this.main.settings.cmp
if (this.settings.enabled) {
this.addDidomi()
if (this.settings.payEnabled) {
this.addPayOkay()
}
} else if (!window.__tcfapi) {
addTCFStub() // Fallback for missing TCF stub
}
}
/**
* Load Didomi SDK, documentation at developers.didomi.io
*/
addDidomi () {
if (window.Didomi || window.didomiLoaded) {
cpexWarn('CMP: Didomi already loaded')
this.loaded = true
} else {
addTCFStub()
// Load Didomi SDK
window.didomiConfig = window.didomiConfig || {}
window.didomiConfig.sdkPath = window.didomiConfig.sdkPath || 'https://sdk.privacy-center.org/'
window.didomiEventListeners = window.didomiEventListeners || []
window.didomiOnReady = window.didomiOnReady || []
const hostname = this.main.localhost ? 'cpex.cz' : document.location.hostname
const target = this.settings.didomiTemplate ? '?target_type=notice&target=' + this.settings.didomiTemplate : '?target=' + hostname
let loaderPath = window.didomiConfig.sdkPath + '9a8e2159-3781-4da1-9590-fbf86806f86e/loader.js' + target
if (window.didomiConfig.user) {
const user = window.didomiConfig.user
const country = user.country
const region = user.region
if (country) {
loaderPath = loaderPath + '&country=' + country
if (region) { loaderPath = loaderPath + '®ion=' + region }
}
}
addElement('link', document.head, { rel: 'preconnect', as: 'script', href: window.didomiConfig.sdkPath })
addElement('link', document.head, { rel: 'dns-prefetch', as: 'script', href: window.didomiConfig.sdkPath })
loadScript(document, loaderPath, 'Didomi loader for SDK')
window.didomiLoaded = true
window.didomiOnReady.push(() => {
this.loaded = true
// Protect against stub misconfiguration
window.__tcfapi.stubVersion = 2
cpexLog('CMP: Didomi loaded')
// Protect against Didomi misconfiguration
if (window.Didomi.isTCFEnabled() === false) { cpexError('TCF compliance disabled in Didomi console') }
// Add close button
if (typeof window.cpexCmpAllowCloseButton !== 'undefined' || window.location.href.indexOf('cpexCmpAllowCloseButton') !== -1) {
this.addCloseButton()
}
})
}
}
/**
* Load Pay or Okay variant - our custom modal, an extension built on top of Didomi SDK
*/
addPayOkay () {
window.didomiOnReady.push((didomi) => { // render once didomi is ready
if (didomi.isConsentRequired()) { // dont show for bots
this.pay = new PayOkay(this.main)
window.didomiEventListeners.push({ event: 'preferences.clicksavechoices', listener: () => { this.pay.hideModal() } })
window.didomiEventListeners.push({ event: 'preferences.clickagreetoall', listener: () => { this.pay.hideModal() } })
}
})
}
/**
* Based on task FED-311: Adds close button to the banner, in specific circumstances
*/
addCloseButton () {
const targetEl = document.getElementById('didomi-notice') || document.getElementsByClassName('didomi-popup-notice-logo-container')[0] // For both banner and popup
if (targetEl) {
const closeButton = document.createElement('div')
closeButton.textContent = '×'
closeButton.style.cssText = 'position: absolute; top: 10px; right: 10px; width: 40px; height: 40px; cursor: pointer; font-size: 20pt; text-align: center; line-height: 40px;'
closeButton.addEventListener('click', function () { window.Didomi.notice.hide() })
targetEl.appendChild(closeButton)
}
}
}
// Store and CPEx consent with every change
window.didomiEventListeners = window.didomiEventListeners || []
window.didomiEventListeners.push({
event: 'consent.changed',
listener: async () => {
const consent = window.Didomi.getUserConsentStatusForAll()
if (consent && consent.vendors) {
window.__tcfapi('addEventListener', 2, (data, success) => {
if (success === false) { return }
setCookie('cpxc', 2592000, data.vendor.consents[570] ? '1' : '0') // save consent status for one month
})
}
}
})