| 1 |
/** |
| 2 |
* Age Gate widget behavior. |
| 3 |
* |
| 4 |
* This script renders a global overlay. It must initialize once per page load, |
| 5 |
* and should also work inside Elementor preview without duplicating DOM nodes. |
| 6 |
*/ |
| 7 |
(function () { |
| 8 |
"use strict"; |
| 9 |
|
| 10 |
const FLAG = "kingAddonsAgeGateInitialized"; |
| 11 |
|
| 12 |
// Module-scoped references used by helpers like setStatus()/closeOverlay(). |
| 13 |
// These are assigned during init() and remain available for button handlers. |
| 14 |
let payload = null; |
| 15 |
let root = null; |
| 16 |
let state = null; |
| 17 |
|
| 18 |
/** |
| 19 |
* Initialize Age Gate once. |
| 20 |
* |
| 21 |
* @returns {void} |
| 22 |
*/ |
| 23 |
const init = () => { |
| 24 |
payload = window.kingAddonsAgeGate; |
| 25 |
if (!payload || !payload.enabled) { |
| 26 |
return; |
| 27 |
} |
| 28 |
|
| 29 |
if (window[FLAG]) { |
| 30 |
return; |
| 31 |
} |
| 32 |
|
| 33 |
if (!document.body) { |
| 34 |
// Defer until body is available. |
| 35 |
setTimeout(init, 0); |
| 36 |
return; |
| 37 |
} |
| 38 |
|
| 39 |
window[FLAG] = true; |
| 40 |
|
| 41 |
root = ensureRoot(); |
| 42 |
const card = root.querySelector('.king-addons-age-gate__card'); |
| 43 |
const content = root.querySelector('.king-addons-age-gate__content'); |
| 44 |
state = { |
| 45 |
status: payload.status || '', |
| 46 |
cookieDays: resolveCookieDays(payload), |
| 47 |
}; |
| 48 |
|
| 49 |
if (!card || !content) { |
| 50 |
return; |
| 51 |
} |
| 52 |
|
| 53 |
applyDesign(root, card, payload); |
| 54 |
|
| 55 |
const needsBlock = |
| 56 |
payload.behaviour && |
| 57 |
payload.behaviour.denyAction === 'block' && |
| 58 |
state.status === 'denied'; |
| 59 |
|
| 60 |
if (!payload.shouldRender && !needsBlock) { |
| 61 |
return; |
| 62 |
} |
| 63 |
|
| 64 |
lockScroll(); |
| 65 |
showOverlay(root, payload); |
| 66 |
|
| 67 |
if (payload.elementorTemplate) { |
| 68 |
const templateWrapper = document.createElement('div'); |
| 69 |
templateWrapper.className = 'king-addons-age-gate__template'; |
| 70 |
templateWrapper.innerHTML = payload.elementorTemplate; |
| 71 |
content.appendChild(templateWrapper); |
| 72 |
} |
| 73 |
|
| 74 |
if (needsBlock) { |
| 75 |
renderBlocked(content, payload); |
| 76 |
return; |
| 77 |
} |
| 78 |
|
| 79 |
if (payload.mode === 'dob' && payload.isPremium) { |
| 80 |
renderDob(content, payload, state); |
| 81 |
} else { |
| 82 |
renderYesNo(content, payload, state); |
| 83 |
} |
| 84 |
}; |
| 85 |
|
| 86 |
const initWhenReady = () => { |
| 87 |
if (document.readyState === "loading") { |
| 88 |
document.addEventListener("DOMContentLoaded", init); |
| 89 |
return; |
| 90 |
} |
| 91 |
init(); |
| 92 |
}; |
| 93 |
|
| 94 |
initWhenReady(); |
| 95 |
|
| 96 |
// Elementor preview support: run init after Elementor frontend bootstrap. |
| 97 |
if (typeof jQuery !== "undefined") { |
| 98 |
jQuery(window).on("elementor/frontend/init", function () { |
| 99 |
init(); |
| 100 |
}); |
| 101 |
} |
| 102 |
|
| 103 |
/** |
| 104 |
* Creates root container if not present. |
| 105 |
*/ |
| 106 |
function ensureRoot() { |
| 107 |
let rootEl = document.getElementById('king-addons-age-gate'); |
| 108 |
if (!rootEl) { |
| 109 |
rootEl = document.createElement('div'); |
| 110 |
rootEl.id = 'king-addons-age-gate'; |
| 111 |
rootEl.className = 'king-addons-age-gate'; |
| 112 |
rootEl.innerHTML = '<div class="king-addons-age-gate__overlay"></div><div class="king-addons-age-gate__card"><div class="king-addons-age-gate__content"></div></div>'; |
| 113 |
document.body.appendChild(rootEl); |
| 114 |
} |
| 115 |
return rootEl; |
| 116 |
} |
| 117 |
|
| 118 |
/** |
| 119 |
* Applies design variables to the overlay. |
| 120 |
*/ |
| 121 |
function applyDesign(rootEl, cardEl, data) { |
| 122 |
const design = data.design || {}; |
| 123 |
|
| 124 |
// Reset template + animation modifiers (important for Elementor preview re-init). |
| 125 |
const templateClasses = [ |
| 126 |
'king-addons-age-gate--template-center-card', |
| 127 |
'king-addons-age-gate--template-bottom-card', |
| 128 |
'king-addons-age-gate--template-top-card', |
| 129 |
'king-addons-age-gate--template-side-left', |
| 130 |
'king-addons-age-gate--template-side-right', |
| 131 |
'king-addons-age-gate--template-fullscreen', |
| 132 |
]; |
| 133 |
templateClasses.forEach((cls) => rootEl.classList.remove(cls)); |
| 134 |
Array.from(rootEl.classList) |
| 135 |
.filter((cls) => cls.indexOf('king-addons-age-gate--animate-') === 0) |
| 136 |
.forEach((cls) => rootEl.classList.remove(cls)); |
| 137 |
|
| 138 |
cardEl.classList.remove('king-addons-age-gate__card--bottom'); |
| 139 |
cardEl.classList.remove('king-addons-age-gate__card--top'); |
| 140 |
|
| 141 |
const existingBg = cardEl.querySelector('.king-addons-age-gate__background'); |
| 142 |
if (existingBg) { |
| 143 |
existingBg.remove(); |
| 144 |
} |
| 145 |
|
| 146 |
const overlayColor = (design.overlayColor || '#0d0d0d').toString(); |
| 147 |
const overlayOpacity = clamp01(design.overlayOpacity ?? 0.7); |
| 148 |
rootEl.style.setProperty('--ka-age-overlay', overlayColor); |
| 149 |
rootEl.style.setProperty('--ka-age-overlay-opacity', overlayOpacity); |
| 150 |
rootEl.style.setProperty('--ka-age-overlay-rgba', toRgba(overlayColor, overlayOpacity) || ('rgba(13, 13, 13, ' + overlayOpacity + ')')); |
| 151 |
rootEl.style.setProperty('--ka-age-card-bg', design.cardBackground || '#ffffff'); |
| 152 |
rootEl.style.setProperty('--ka-age-card-width', (design.cardWidth || 520) + 'px'); |
| 153 |
rootEl.style.setProperty('--ka-age-text', design.textColor || '#111827'); |
| 154 |
rootEl.style.setProperty('--ka-age-title-size', (design.titleSize || 24) + 'px'); |
| 155 |
rootEl.style.setProperty('--ka-age-body-size', (design.bodySize || 16) + 'px'); |
| 156 |
rootEl.style.setProperty('--ka-age-title-weight', design.titleWeight || 700); |
| 157 |
rootEl.style.setProperty('--ka-age-body-weight', design.bodyWeight || 400); |
| 158 |
rootEl.style.setProperty('--ka-age-btn-yes-color', design.buttonYesColor || '#ffffff'); |
| 159 |
rootEl.style.setProperty('--ka-age-btn-yes-bg', design.buttonYesBg || '#10b981'); |
| 160 |
rootEl.style.setProperty('--ka-age-btn-no-color', design.buttonNoColor || '#ffffff'); |
| 161 |
rootEl.style.setProperty('--ka-age-btn-no-bg', design.buttonNoBg || '#ef4444'); |
| 162 |
rootEl.style.setProperty('--ka-age-btn-yes-hover-bg', design.buttonYesHoverBg || design.buttonYesBg || '#0f9c75'); |
| 163 |
rootEl.style.setProperty('--ka-age-btn-no-hover-bg', design.buttonNoHoverBg || design.buttonNoBg || '#d92d20'); |
| 164 |
rootEl.style.setProperty('--ka-age-btn-yes-hover-color', design.buttonYesHoverColor || design.buttonYesColor || '#ffffff'); |
| 165 |
rootEl.style.setProperty('--ka-age-btn-no-hover-color', design.buttonNoHoverColor || design.buttonNoColor || '#ffffff'); |
| 166 |
|
| 167 |
const template = (design.template || 'center-card').toString(); |
| 168 |
rootEl.classList.add('king-addons-age-gate--template-' + template); |
| 169 |
|
| 170 |
// Back-compat: old settings may still use cardAlign. |
| 171 |
if (design.cardAlign === 'bottom' || template === 'bottom-card') { |
| 172 |
cardEl.classList.add('king-addons-age-gate__card--bottom'); |
| 173 |
} |
| 174 |
|
| 175 |
if (template === 'top-card' || design.cardAlign === 'top') { |
| 176 |
cardEl.classList.add('king-addons-age-gate__card--top'); |
| 177 |
} |
| 178 |
|
| 179 |
if (design.backgroundImage) { |
| 180 |
const bg = document.createElement('div'); |
| 181 |
bg.className = 'king-addons-age-gate__background'; |
| 182 |
bg.style.backgroundImage = 'url(' + design.backgroundImage + ')'; |
| 183 |
cardEl.prepend(bg); |
| 184 |
} |
| 185 |
|
| 186 |
if (design.animation && design.animation !== 'none') { |
| 187 |
rootEl.classList.add('king-addons-age-gate--animate-' + design.animation); |
| 188 |
} |
| 189 |
} |
| 190 |
|
| 191 |
function clamp01(value) { |
| 192 |
const numberValue = typeof value === 'number' ? value : parseFloat(value); |
| 193 |
if (!Number.isFinite(numberValue)) { |
| 194 |
return 0.7; |
| 195 |
} |
| 196 |
return Math.min(1, Math.max(0, numberValue)); |
| 197 |
} |
| 198 |
|
| 199 |
function toRgba(color, alpha) { |
| 200 |
const c = (color || '').toString().trim(); |
| 201 |
if (!c) { |
| 202 |
return null; |
| 203 |
} |
| 204 |
|
| 205 |
// #RGB / #RRGGBB |
| 206 |
if (c[0] === '#') { |
| 207 |
let hex = c.slice(1); |
| 208 |
if (hex.length === 3) { |
| 209 |
hex = hex.split('').map((ch) => ch + ch).join(''); |
| 210 |
} |
| 211 |
if (hex.length !== 6) { |
| 212 |
return null; |
| 213 |
} |
| 214 |
const r = parseInt(hex.slice(0, 2), 16); |
| 215 |
const g = parseInt(hex.slice(2, 4), 16); |
| 216 |
const b = parseInt(hex.slice(4, 6), 16); |
| 217 |
if ([r, g, b].some((n) => Number.isNaN(n))) { |
| 218 |
return null; |
| 219 |
} |
| 220 |
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')'; |
| 221 |
} |
| 222 |
|
| 223 |
// rgb(r, g, b) |
| 224 |
const rgbMatch = c.match(/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i); |
| 225 |
if (rgbMatch) { |
| 226 |
return 'rgba(' + rgbMatch[1] + ', ' + rgbMatch[2] + ', ' + rgbMatch[3] + ', ' + alpha + ')'; |
| 227 |
} |
| 228 |
|
| 229 |
// rgba(r, g, b, a) -> replace alpha |
| 230 |
const rgbaMatch = c.match(/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*([0-9.]+)\s*\)$/i); |
| 231 |
if (rgbaMatch) { |
| 232 |
return 'rgba(' + rgbaMatch[1] + ', ' + rgbaMatch[2] + ', ' + rgbaMatch[3] + ', ' + alpha + ')'; |
| 233 |
} |
| 234 |
|
| 235 |
return null; |
| 236 |
} |
| 237 |
|
| 238 |
/** |
| 239 |
* Shows the overlay. |
| 240 |
*/ |
| 241 |
function showOverlay(rootEl, data) { |
| 242 |
rootEl.classList.add('king-addons-age-gate--visible'); |
| 243 |
rootEl.setAttribute('aria-hidden', 'false'); |
| 244 |
const overlay = rootEl.querySelector('.king-addons-age-gate__overlay'); |
| 245 |
if (overlay) { |
| 246 |
overlay.setAttribute('aria-hidden', 'true'); |
| 247 |
} |
| 248 |
} |
| 249 |
|
| 250 |
/** |
| 251 |
* Renders simple Yes/No mode. |
| 252 |
*/ |
| 253 |
function renderYesNo(wrapper, data, localState) { |
| 254 |
wrapper.innerHTML = ''; |
| 255 |
const title = document.createElement('h2'); |
| 256 |
title.className = 'king-addons-age-gate__title'; |
| 257 |
title.textContent = data.texts.title; |
| 258 |
|
| 259 |
const subtitle = document.createElement('p'); |
| 260 |
subtitle.className = 'king-addons-age-gate__subtitle'; |
| 261 |
subtitle.textContent = data.mode === 'minimum' |
| 262 |
? data.texts.subtitle + ' (' + data.minAge + '+)' |
| 263 |
: data.texts.subtitle; |
| 264 |
|
| 265 |
const buttons = document.createElement('div'); |
| 266 |
buttons.className = 'king-addons-age-gate__buttons'; |
| 267 |
|
| 268 |
const yesBtn = buildButton('king-addons-age-gate__button king-addons-age-gate__button--allow', data.texts.yes); |
| 269 |
const noBtn = buildButton('king-addons-age-gate__button king-addons-age-gate__button--deny', data.texts.no); |
| 270 |
|
| 271 |
const consent = buildConsent(data); |
| 272 |
|
| 273 |
yesBtn.addEventListener('click', () => { |
| 274 |
if (consent && !consent.checkbox.checked) { |
| 275 |
showMessage(wrapper, data.behaviour.blockMessage || 'Please confirm consent.'); |
| 276 |
return; |
| 277 |
} |
| 278 |
setStatus('allowed', localState.cookieDays); |
| 279 |
closeOverlay(); |
| 280 |
}); |
| 281 |
|
| 282 |
noBtn.addEventListener('click', () => { |
| 283 |
setStatus('denied', localState.cookieDays); |
| 284 |
if (data.behaviour.denyAction === 'redirect' && data.behaviour.denyRedirectUrl) { |
| 285 |
window.location.href = data.behaviour.denyRedirectUrl; |
| 286 |
} else { |
| 287 |
renderBlocked(wrapper, data); |
| 288 |
} |
| 289 |
}); |
| 290 |
|
| 291 |
buttons.appendChild(yesBtn); |
| 292 |
buttons.appendChild(noBtn); |
| 293 |
|
| 294 |
appendLogo(wrapper, data.design); |
| 295 |
wrapper.appendChild(title); |
| 296 |
wrapper.appendChild(subtitle); |
| 297 |
if (consent) { |
| 298 |
wrapper.appendChild(consent.container); |
| 299 |
} |
| 300 |
wrapper.appendChild(buttons); |
| 301 |
} |
| 302 |
|
| 303 |
/** |
| 304 |
* Renders DOB form. |
| 305 |
*/ |
| 306 |
function renderDob(wrapper, data, localState) { |
| 307 |
wrapper.innerHTML = ''; |
| 308 |
const dobConfig = data.dob || { format: 'dmy', errors: { invalid: 'Invalid date.', denied: 'Access denied.' } }; |
| 309 |
|
| 310 |
const title = document.createElement('h2'); |
| 311 |
title.className = 'king-addons-age-gate__title'; |
| 312 |
title.textContent = data.texts.title; |
| 313 |
|
| 314 |
const subtitle = document.createElement('p'); |
| 315 |
subtitle.className = 'king-addons-age-gate__subtitle'; |
| 316 |
subtitle.textContent = data.texts.subtitle + ' (' + data.minAge + '+)'; |
| 317 |
|
| 318 |
const grid = document.createElement('div'); |
| 319 |
grid.className = 'king-addons-age-gate__field-grid'; |
| 320 |
|
| 321 |
const inputs = buildDobInputs(dobConfig.format || 'dmy'); |
| 322 |
inputs.forEach((input) => grid.appendChild(input)); |
| 323 |
|
| 324 |
const consent = buildConsent(data); |
| 325 |
|
| 326 |
const buttons = document.createElement('div'); |
| 327 |
buttons.className = 'king-addons-age-gate__buttons'; |
| 328 |
const submitBtn = buildButton('king-addons-age-gate__button king-addons-age-gate__button--allow', data.texts.yes); |
| 329 |
const declineBtn = buildButton('king-addons-age-gate__button king-addons-age-gate__button--deny', data.texts.no); |
| 330 |
|
| 331 |
const message = document.createElement('div'); |
| 332 |
message.className = 'king-addons-age-gate__message'; |
| 333 |
message.style.display = 'none'; |
| 334 |
|
| 335 |
submitBtn.addEventListener('click', () => { |
| 336 |
if (consent && !consent.checkbox.checked) { |
| 337 |
showMessage(wrapper, data.behaviour.blockMessage || dobConfig.errors.invalid); |
| 338 |
return; |
| 339 |
} |
| 340 |
message.style.display = 'none'; |
| 341 |
const params = new URLSearchParams(); |
| 342 |
params.append('action', data.ajax.action); |
| 343 |
params.append('nonce', data.ajax.nonce); |
| 344 |
params.append('day', inputs.day.value || ''); |
| 345 |
params.append('month', inputs.month.value || ''); |
| 346 |
params.append('year', inputs.year.value || ''); |
| 347 |
|
| 348 |
submitBtn.disabled = true; |
| 349 |
submitBtn.textContent = data.texts.yes + '...'; |
| 350 |
|
| 351 |
fetch(data.ajax.url, { |
| 352 |
method: 'POST', |
| 353 |
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}, |
| 354 |
body: params.toString(), |
| 355 |
}).then((response) => response.json()) |
| 356 |
.then((resp) => { |
| 357 |
if (resp && resp.success) { |
| 358 |
setStatus('allowed', localState.cookieDays); |
| 359 |
closeOverlay(); |
| 360 |
} else { |
| 361 |
const msg = resp && resp.data && resp.data.message ? resp.data.message : dobConfig.errors.denied; |
| 362 |
showInlineMessage(msg); |
| 363 |
setStatus('denied', localState.cookieDays); |
| 364 |
} |
| 365 |
}) |
| 366 |
.catch(() => { |
| 367 |
showInlineMessage(dobConfig.errors.invalid); |
| 368 |
}) |
| 369 |
.finally(() => { |
| 370 |
submitBtn.disabled = false; |
| 371 |
submitBtn.textContent = data.texts.yes; |
| 372 |
}); |
| 373 |
}); |
| 374 |
|
| 375 |
declineBtn.addEventListener('click', () => { |
| 376 |
setStatus('denied', localState.cookieDays); |
| 377 |
if (data.behaviour.denyAction === 'redirect' && data.behaviour.denyRedirectUrl) { |
| 378 |
window.location.href = data.behaviour.denyRedirectUrl; |
| 379 |
} else { |
| 380 |
renderBlocked(wrapper, data); |
| 381 |
} |
| 382 |
}); |
| 383 |
|
| 384 |
buttons.appendChild(submitBtn); |
| 385 |
buttons.appendChild(declineBtn); |
| 386 |
|
| 387 |
appendLogo(wrapper, data.design); |
| 388 |
wrapper.appendChild(title); |
| 389 |
wrapper.appendChild(subtitle); |
| 390 |
wrapper.appendChild(grid); |
| 391 |
if (consent) { |
| 392 |
wrapper.appendChild(consent.container); |
| 393 |
} |
| 394 |
wrapper.appendChild(buttons); |
| 395 |
wrapper.appendChild(message); |
| 396 |
|
| 397 |
function showInlineMessage(text) { |
| 398 |
message.textContent = text; |
| 399 |
message.style.display = 'block'; |
| 400 |
} |
| 401 |
} |
| 402 |
|
| 403 |
/** |
| 404 |
* Builds DOB inputs based on format. |
| 405 |
*/ |
| 406 |
function buildDobInputs(format) { |
| 407 |
const day = document.createElement('input'); |
| 408 |
day.type = 'number'; |
| 409 |
day.min = '1'; |
| 410 |
day.max = '31'; |
| 411 |
day.placeholder = 'DD'; |
| 412 |
day.className = 'king-addons-age-gate__input'; |
| 413 |
|
| 414 |
const month = document.createElement('input'); |
| 415 |
month.type = 'number'; |
| 416 |
month.min = '1'; |
| 417 |
month.max = '12'; |
| 418 |
month.placeholder = 'MM'; |
| 419 |
month.className = 'king-addons-age-gate__input'; |
| 420 |
|
| 421 |
const year = document.createElement('input'); |
| 422 |
year.type = 'number'; |
| 423 |
year.min = '1900'; |
| 424 |
year.placeholder = 'YYYY'; |
| 425 |
year.className = 'king-addons-age-gate__input'; |
| 426 |
|
| 427 |
const parts = []; |
| 428 |
if (format === 'mdy') { |
| 429 |
parts.push(month, day, year); |
| 430 |
} else if (format === 'ymd') { |
| 431 |
parts.push(year, month, day); |
| 432 |
} else { |
| 433 |
parts.push(day, month, year); |
| 434 |
} |
| 435 |
|
| 436 |
parts.day = day; |
| 437 |
parts.month = month; |
| 438 |
parts.year = year; |
| 439 |
return parts; |
| 440 |
} |
| 441 |
|
| 442 |
/** |
| 443 |
* Renders blocked message. |
| 444 |
*/ |
| 445 |
function renderBlocked(wrapper, data) { |
| 446 |
wrapper.innerHTML = ''; |
| 447 |
const title = document.createElement('h2'); |
| 448 |
title.className = 'king-addons-age-gate__title'; |
| 449 |
title.textContent = data.texts.title; |
| 450 |
|
| 451 |
const message = document.createElement('p'); |
| 452 |
message.className = 'king-addons-age-gate__message'; |
| 453 |
message.style.display = 'block'; |
| 454 |
message.textContent = data.behaviour.blockMessage || data.texts.block; |
| 455 |
|
| 456 |
appendLogo(wrapper, data.design); |
| 457 |
wrapper.appendChild(title); |
| 458 |
wrapper.appendChild(message); |
| 459 |
|
| 460 |
if (data.behaviour.denyRedirectUrl) { |
| 461 |
const buttons = document.createElement('div'); |
| 462 |
buttons.className = 'king-addons-age-gate__buttons'; |
| 463 |
const goBtn = buildButton('king-addons-age-gate__button king-addons-age-gate__button--allow', data.texts.no); |
| 464 |
goBtn.addEventListener('click', () => { |
| 465 |
window.location.href = data.behaviour.denyRedirectUrl; |
| 466 |
}); |
| 467 |
buttons.appendChild(goBtn); |
| 468 |
wrapper.appendChild(buttons); |
| 469 |
} |
| 470 |
} |
| 471 |
|
| 472 |
/** |
| 473 |
* Builds consent checkbox if required. |
| 474 |
*/ |
| 475 |
function buildConsent(data) { |
| 476 |
if (!data.behaviour || !data.behaviour.consentCheckbox) { |
| 477 |
return null; |
| 478 |
} |
| 479 |
const container = document.createElement('label'); |
| 480 |
container.className = 'king-addons-age-gate__subtitle'; |
| 481 |
const checkbox = document.createElement('input'); |
| 482 |
checkbox.type = 'checkbox'; |
| 483 |
checkbox.style.marginRight = '8px'; |
| 484 |
container.appendChild(checkbox); |
| 485 |
const labelText = data.behaviour.consentLabel || 'I agree to the policy.'; |
| 486 |
container.appendChild(document.createTextNode(labelText)); |
| 487 |
return {container, checkbox}; |
| 488 |
} |
| 489 |
|
| 490 |
/** |
| 491 |
* Utility to create button. |
| 492 |
*/ |
| 493 |
function buildButton(classes, text) { |
| 494 |
const button = document.createElement('button'); |
| 495 |
button.type = 'button'; |
| 496 |
button.className = classes; |
| 497 |
button.textContent = text; |
| 498 |
return button; |
| 499 |
} |
| 500 |
|
| 501 |
/** |
| 502 |
* Appends logo if provided. |
| 503 |
*/ |
| 504 |
function appendLogo(wrapper, design) { |
| 505 |
if (!design || !design.logo) { |
| 506 |
return; |
| 507 |
} |
| 508 |
const logo = document.createElement('img'); |
| 509 |
logo.src = design.logo; |
| 510 |
logo.alt = ''; |
| 511 |
logo.className = 'king-addons-age-gate__logo'; |
| 512 |
wrapper.appendChild(logo); |
| 513 |
} |
| 514 |
|
| 515 |
/** |
| 516 |
* Shows a toast-like message within wrapper. |
| 517 |
*/ |
| 518 |
function showMessage(wrapper, text) { |
| 519 |
let message = wrapper.querySelector('.king-addons-age-gate__message'); |
| 520 |
if (!message) { |
| 521 |
message = document.createElement('div'); |
| 522 |
message.className = 'king-addons-age-gate__message'; |
| 523 |
wrapper.appendChild(message); |
| 524 |
} |
| 525 |
message.textContent = text; |
| 526 |
message.style.display = 'block'; |
| 527 |
} |
| 528 |
|
| 529 |
/** |
| 530 |
* Sets cookie and updates state. |
| 531 |
*/ |
| 532 |
function setStatus(status, days) { |
| 533 |
if (payload && payload.cookie && payload.cookie.name) { |
| 534 |
const revision = payload.cookie.revision ? payload.cookie.revision : ''; |
| 535 |
const value = encodeURIComponent(status + '|' + revision); |
| 536 |
let cookie = payload.cookie.name + '=' + value + '; path=/; SameSite=Lax'; |
| 537 |
if (payload.cookie.domain) { |
| 538 |
cookie += '; domain=' + payload.cookie.domain; |
| 539 |
} |
| 540 |
if (days > 0) { |
| 541 |
const date = new Date(); |
| 542 |
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); |
| 543 |
cookie += '; expires=' + date.toUTCString(); |
| 544 |
} |
| 545 |
document.cookie = cookie; |
| 546 |
} |
| 547 |
|
| 548 |
if (state) { |
| 549 |
state.status = status; |
| 550 |
} |
| 551 |
} |
| 552 |
|
| 553 |
/** |
| 554 |
* Locks document scroll. |
| 555 |
*/ |
| 556 |
function lockScroll() { |
| 557 |
document.documentElement.dataset.kaAgeGateScroll = document.documentElement.style.overflow || ''; |
| 558 |
document.documentElement.style.overflow = 'hidden'; |
| 559 |
} |
| 560 |
|
| 561 |
/** |
| 562 |
* Restores scroll and hides overlay. |
| 563 |
*/ |
| 564 |
function closeOverlay() { |
| 565 |
const previous = document.documentElement.dataset.kaAgeGateScroll || ''; |
| 566 |
document.documentElement.style.overflow = previous; |
| 567 |
if (root) { |
| 568 |
root.classList.remove('king-addons-age-gate--visible'); |
| 569 |
} |
| 570 |
} |
| 571 |
|
| 572 |
/** |
| 573 |
* Cookie days resolver based on behaviour. |
| 574 |
*/ |
| 575 |
function resolveCookieDays(data) { |
| 576 |
if (data.behaviour && data.behaviour.repeatMode) { |
| 577 |
if (data.behaviour.repeatMode === 'session') { |
| 578 |
return 0; |
| 579 |
} |
| 580 |
if (data.behaviour.repeatMode === 'once') { |
| 581 |
return 3650; |
| 582 |
} |
| 583 |
if (data.behaviour.repeatMode === 'days') { |
| 584 |
return data.behaviour.repeatDays || data.cookie.days || 30; |
| 585 |
} |
| 586 |
} |
| 587 |
return data.cookie && data.cookie.days ? data.cookie.days : 30; |
| 588 |
} |
| 589 |
})(); |
| 590 |
|
| 591 |
|
| 592 |
|
| 593 |
|