/*KS*/ var Interactor = function (config) { // Call Initialization on Interactor Call this.__init__(config); }; Interactor.prototype = { // Initialization __init__: function (config) { var interactor = this; // Argument Assignment // Type Checks // Default Values interactor.interactions = typeof(config.interactions) == "boolean" ? config.interactions : true, interactor.interactionElement = typeof(config.interactionElement) == "string" ? config.interactionElement :'interaction', interactor.interactionEvents = Array.isArray(config.interactionEvents) === true ? config.interactionEvents : ['mouseup', 'touchend'], interactor.conversions = typeof(config.conversions) == "boolean" ? config.conversions : true, interactor.conversionElement = typeof(config.conversionElement) == "string" ? config.conversionElement : 'conversion', interactor.conversionEvents = Array.isArray(config.conversionEvents) === true ? config.conversionEvents : ['mouseup', 'touchend'], interactor.endpoint = typeof(config.endpoint) == "string" ? config.endpoint : '/interactions', interactor.async = typeof(config.async) == "boolean" ? config.async : true, interactor.debug = typeof(config.debug) == "boolean" ? config.debug : true, interactor.detectLastClick = typeof(config.detectLastClick) == "boolean" ? config.detectLastClick : true, interactor.records = [], interactor.session = {}, interactor.loadTime = new Date(); // Initialize Session interactor.__initializeSession__(); // Call Event Binding Method interactor.__bindEvents__(); return interactor; }, // Create Events to Track __bindEvents__: function () { var interactor = this; // Set Interaction Capture if (interactor.interactions === true) { for (var i = 0; i < interactor.interactionEvents.length; i++) { document.addEventListener(interactor.interactionEvents[i], function (e) { //e.stopPropagation(); if (e.target.classList.value === interactor.interactionElement) { interactor.__addInteraction__(e, "interaction"); } }); } } // Set Conversion Capture if (interactor.conversions === true) { for (var j = 0; j < interactor.conversionEvents.length; j++) { document.querySelector('body').addEventListener(interactor.conversionEvents[j], function (e) { e.stopPropagation(); if (e.target.classList.value === interactor.conversionElement) { interactor.__addInteraction__(e, "conversion"); } }); } } if (interactor.detectLastClick === true) { // Moved to server side ... } /* // Bind onbeforeunload Event window.addEventListener("beforeunload", function(event) { interactor.__sendInteractions__(); }); */ document.addEventListener("DOMContentLoaded", function(e) { interactor.__addInteraction__(e, "visit"); interactor.__sendInteractions__(); }); document.querySelector('body').addEventListener("promocode", function(e) { interactor.__addInteraction__(e, "promocode"); const _promocodePathName = '/cart/', _promocodeOrigin = window.location.origin, _promocodeParams = '?utm_source=blogger&utm_medium=blogger_promocode&utm_campaign='+e.detail.promocode+'&utm_content='+e.detail.native+'&utm_term=cart'; interactor.session.page.location = _promocodePathName; interactor.session.page.origin = origin; interactor.session.page.href = _promocodeOrigin+_promocodePathName+_promocodeParams; interactor.__sendInteractions__(); }); return interactor; }, // Add Interaction Object Triggered By Events to Records Array __addInteraction__: function (e, type) { var interactor = this, // Interaction Object interaction = { type : type, event : e.type, targetTag : e.target.nodeName, targetClasses : e.target.className, content : e.target.innerText, clientPosition : { x : e.clientX, y : e.clientY }, screenPosition : { x : e.screenX, y : e.screenY }, createdAt : new Date() }; // Insert into Records Array interactor.records.push(interaction); // Log Interaction if Debugging if (interactor.debug) { // Close Session & Log to Console interactor.__closeSession__(); //console.log("Session:\n", interactor.session); } return interactor; }, // Generate Session Object & Assign to Session Property __initializeSession__: function () { var cookieName = 'kt_t', interactor = this; function setCookie(name,value,days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days*24*60*60*1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } function getCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)===' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length); } return null; } function generateUUIDv4() { return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); } function getUserUUID() { let uuid = getCookie(cookieName); if (uuid === null) { uuid = generateUUIDv4(); setCookie(cookieName, uuid, 90); setCookie('kt_r', '1', 90); } else { setCookie(cookieName, uuid, 90); } return uuid; } function getWcId() { const value = `; ${document.cookie}`; const parts = value.split(`; wcid=`); if (parts.length === 2) return parts.pop().split(';').shift(); return ''; } // Assign Session Property interactor.session = { user : getUserUUID(), wcid : getWcId(), io : ((typeof websiteIsOpt !== "undefined") && websiteIsOpt === 1), loadTime : interactor.loadTime, unloadTime : new Date(), language : window.navigator.language, platform : window.navigator.platform, port : window.location.port, clientStart : { name : window.navigator.appVersion, innerWidth : window.innerWidth, innerHeight : window.innerHeight, outerWidth : window.outerWidth, outerHeight : window.outerHeight }, page : { location : window.location.pathname, href : window.location.href, origin : window.location.origin, title : document.title, referrer : document.referrer }, endpoint : interactor.endpoint }; fetch('/kremlinstore_t_w').then(() => { fetch('/kremlinstore_t_r').then(); }); return interactor; }, // Insert End of Session Values into Session Property __closeSession__: function () { var interactor = this; // Assign Session Properties interactor.session.unloadTime = new Date(); interactor.session.interactions = interactor.records; interactor.session.clientEnd = { name : window.navigator.appVersion, innerWidth : window.innerWidth, innerHeight : window.innerHeight, outerWidth : window.outerWidth, outerHeight : window.outerHeight }; return interactor; }, // Gather Additional Data and Send Interaction(s) to Server __sendInteractions__: function () { var interactor = this, // Initialize Cross Header Request xhr = new XMLHttpRequest(); // Close Session interactor.__closeSession__(); // Post Session Data Serialized as JSON xhr.open('POST', interactor.endpoint, interactor.async); xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); xhr.send(JSON.stringify(interactor.session)); interactor.interactions = []; interactor.records = [] return interactor; } }; var interactions = new Interactor({ interactions : true, interactionElement : "interaction", interactionEvents : ["load", "click", "mousedown", "mouseup", "touchstart", "touchend"], conversions : true, conversionElement : "conversion", conversionEvents : ["mouseup", "touchend"], endpoint : '/kt.tmp', async : true, debug : true, detectLastClick : true, });