class Media2Click {
#cookieHosts = [];
#lifetime = -1;
constructor(lifetime = -1) {
console.log(lifetime);
this.setCookieLifetime(lifetime);
this.#cookieHosts = this.#getCookieHosts();
let thisObject = this;
let elementList = document.querySelectorAll('.media2click-wrap');
elementList.forEach(function(element) {
thisObject.#initElement(element);
});
let toggleList = document.querySelectorAll('.media2click-toggle');
toggleList.forEach( function (toggle) {
thisObject.#initToggle(toggle);
});
}
/**
* Initialise a placeholder element
* @param element
*/
#initElement(element) {
let thisObject = this;
let placeholder = element.querySelector('.media2click-placeholder');
let host = '';
if (placeholder !== null) {
host = placeholder.getAttribute('data-host');
let type = 'iframe';
if (placeholder.classList.contains('media2click-placeholder-content')) {
type = 'content';
}
let contentData = element.querySelector('.media2click-contentdata');
let frameData = element.querySelector('.media2click-iframedata');
let activateOnce = element.querySelector('.media2click-once');
let activatePermanent = element.querySelector('.media2click-permanent');
/* Activate once and load iframe */
if (activateOnce !== null) {
activateOnce.addEventListener('click', function(event) {
event.preventDefault();
if (type === 'content') {
thisObject.#activateContent(contentData, placeholder);
} else {
thisObject.#activateFrame(frameData, placeholder);
}
}, false);
}
/* Activate permanently and load iframe */
if (activatePermanent !== null) {
activatePermanent.addEventListener('click', function(event) {
event.preventDefault();
thisObject.addHost(host);
if (type === 'content') {
thisObject.#activateContent(contentData, placeholder);
} else {
thisObject.#activateFrame(frameData, placeholder);
}
}, false);
}
/* If already activated permanently, load iframe */
if (thisObject.isActiveHost(host)) {
if (type === 'content') {
thisObject.#activateContent(contentData, placeholder);
} else {
thisObject.#activateFrame(frameData, placeholder);
}
}
}
}
/**
* Initialize a toggle element
* @param toggle
*/
#initToggle(toggle) {
let thisObject = this;
let host = toggle.getAttribute('data-host');
if(thisObject.isActiveHost(host)) {
toggle.classList.add('activated');
toggle.setAttribute('checked', 'checked');
}
toggle.addEventListener('click', function (event) {
toggle.classList.toggle('activated');
if (toggle.className === 'media2click-toggle activated') {
thisObject.addHost(host);
} else {
thisObject.removeHost(host);
}
});
}
/**
* Replace media2click dummy element with actual iframe
* @param dataNode
* @param placeholderNode
*/
#activateFrame(dataNode, placeholderNode) {
let newNode = document.createElement('iframe');
let frameData = JSON.parse(dataNode.getAttribute('data-attributes'));
Object.entries(frameData).forEach(([key, value]) => newNode.setAttribute(key, value));
dataNode.parentElement.insertBefore(newNode, dataNode);
dataNode.parentElement.removeChild(dataNode);
placeholderNode.parentElement.removeChild(placeholderNode);
}
#activateContent(contentNode, placeholderNode) {
let newNode = document.createElement('iframe');
let contentData = JSON.parse(contentNode.text);
Object.entries(contentData.attributes).forEach(([key, value]) => newNode.setAttribute(key, value));
contentNode.parentElement.insertBefore(newNode, contentNode);
newNode.contentWindow.document.open();
newNode.contentWindow.document.write('
' + contentData.content + '');
newNode.contentWindow.document.close();
contentNode.parentElement.removeChild(contentNode);
placeholderNode.parentElement.removeChild(placeholderNode);
}
/**
* Set the media2click accepted hosts cookie
*/
#setCookie() {
let uniqueHosts = [...new Set(this.#cookieHosts)];
let expires = '';
if (this.#lifetime > 0) {
let d = new Date();
d.setTime(d.getTime() + (this.#lifetime * 24 * 60 * 60 * 1000));
expires = "expires=" + d.toUTCString() + ";";
}
document.cookie = "m2c_accepted_hosts=" + uniqueHosts.join() + ";" + expires + "path=/;SameSite=Strict";
}
/**
* Get the media2click accepted hosts from cookie
* @returns {string[]}
*/
#getCookieHosts() {
let thisObject = this;
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf("m2c_accepted_hosts=") === 0) {
let hosts = c.substring(19, c.length).split(',');
let uniqueHosts = [...new Set(hosts)];
return uniqueHosts.filter(function(host) {
return thisObject.#isValidHost(host);
});
}
}
return [];
}
/**
* Delete the media2click accepted hosts cookie
*/
#deleteCookie() {
document.cookie = "m2c_accepted_hosts=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
/**
* Check host for validity
* @param host
* @returns {boolean}
*/
#isValidHost(host) {
if (typeof host !== 'string' || host === '') {
return false;
}
return !/[^a-z0-9._-]/i.test(host);
}
/**
* Set the cookie lifetime
* @param lifetime
*/
setCookieLifetime(lifetime) {
lifetime = Number.parseInt(lifetime, 10);
if (Number.isNaN(lifetime) || lifetime < 0) {
lifetime = 7;
}
this.#lifetime = lifetime;
}
/**
*
* @returns {string[]}
*/
getActiveHosts() {
return this.#cookieHosts;
}
/**
* Check if a host is active
* @param host
* @returns {boolean}
*/
isActiveHost(host) {
if (!this.#isValidHost(host)) {
return false;
}
return (this.#cookieHosts.indexOf(host) > -1);
}
/**
* Add a host to the allowed hosts list and update the cookie
* @param host
* @returns {boolean}
*/
addHost(host) {
if (!this.#isValidHost(host)) {
return false;
}
if (!this.isActiveHost(host)) {
this.#cookieHosts.push(host);
this.updateCookie();
}
return true;
}
/**
* Remove a host from the allowed hosts list and update the cookie
* @param host
* @returns {boolean}
*/
removeHost(host) {
if (!this.#isValidHost(host)) {
return false;
}
if (this.isActiveHost(host)) {
this.#cookieHosts.splice(this.#cookieHosts.indexOf(host), 1);
this.updateCookie();
}
return true;
}
/**
* Update the cookie
*/
updateCookie() {
if (this.#cookieHosts.length > 0) {
this.#setCookie();
} else {
this.#deleteCookie();
}
}
/**
* Activate all elements for a selected host
* @param host
* @returns {boolean}
*/
activateAllForHost(host) {
if (!this.#isValidHost(host)) {
return false;
}
let thisObject = this;
let elementList = document.querySelectorAll('.media2click-wrap');
elementList.forEach(function(element) {
let placeholder = element.querySelector('.media2click-placeholder');
let elementHost = '';
if (placeholder !== null) {
elementHost = placeholder.getAttribute('data-host');
let type = 'iframe';
if (placeholder.classList.contains('media2click-placeholder-content')) {
type = 'content';
}
let contentData = element.querySelector('.media2click-contentdata');
let frameData = element.querySelector('.media2click-iframedata');
if (elementHost === host) {
if (type === 'content') {
thisObject.#activateContent(contentData, placeholder);
} else {
thisObject.#activateFrame(frameData, placeholder);
}
}
}
});
return true;
}
}
document.addEventListener('readystatechange', (event) => {
if (event.target.readyState === 'complete') {
if (typeof media2click === 'undefined') {
if (typeof m2cCookieLifetime === 'undefined' || isNaN(m2cCookieLifetime)) {
const media2click = new Media2Click();
} else {
const media2click = new Media2Click(m2cCookieLifetime);
}
}
}
});