banner.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /**
  2. * Wagtail banner script
  3. */
  4. (function initBanner() {
  5. /**
  6. * Util to write a cookie.
  7. *
  8. * @param {string} name
  9. * @param {string} value
  10. * @param {number} days
  11. * @returns {void}
  12. */
  13. function setCookie(name, value, days) {
  14. const date = new Date();
  15. date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
  16. document.cookie = [
  17. [encodeURIComponent(name), '=', encodeURIComponent(value), ';'].join(''),
  18. 'SameSite=Strict;',
  19. ['expires=', date.toGMTString()].join(''),
  20. ].join(' ');
  21. }
  22. /**
  23. * Util to check if the cookie is written.
  24. *
  25. * @param {string} name
  26. * @param {string} value
  27. * @returns {boolean}
  28. */
  29. function hasCookie(name, value) {
  30. return document.cookie.split('; ').indexOf(name + '=' + value) >= 0;
  31. }
  32. const MINIMUM_COOKIE_DURATION = 30;
  33. /**
  34. * Creates the promotion banner based on the element in the DOM.
  35. *
  36. * @returns {void}
  37. */
  38. function createBanner() {
  39. const template = document.querySelector('[data-promotion-banner]');
  40. if (!template) return;
  41. const dateUntil = new Date(template.dataset.dateUntil || 'INACTIVE');
  42. if (!(dateUntil instanceof Date) || Number.isNaN(dateUntil.valueOf())) {
  43. return;
  44. }
  45. // Pause any promotional banner for X days when manually cleared
  46. const cookieDuration = Math.max(
  47. Number(template.dataset.clearDuration || MINIMUM_COOKIE_DURATION),
  48. MINIMUM_COOKIE_DURATION,
  49. );
  50. // Create a cookie name that is unique for this specific promotion's expiry
  51. const cookieName =
  52. 'WAGTAIL_PROMOTION_BANNER_CLEARED_' +
  53. dateUntil.toISOString().substring(0, 10).replaceAll('-', '_');
  54. if (!hasCookie(cookieName, 'true') && new Date() < dateUntil) {
  55. const promotionBanner =
  56. template.content.firstElementChild.cloneNode(true);
  57. promotionBanner
  58. .querySelector('[data-clear]')
  59. // eslint-disable-next-line prefer-arrow-callback
  60. .addEventListener('click', function handleClose() {
  61. setCookie(cookieName, 'true', cookieDuration);
  62. promotionBanner.remove();
  63. });
  64. document.querySelector('main').prepend(promotionBanner);
  65. }
  66. }
  67. document.addEventListener('DOMContentLoaded', createBanner);
  68. })();