/* only run JS code when all DOM & content is loaded */ window.onload = function() { var agent = navigator.userAgent; var domain = window.location.hostname; var page = window.location.pathname; var timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; var scrollPercentage = 0; var sessionId = sessionSet(); var browserId = browserSet(); var referrer = document.referrer; if (referrer === '') { referrer = 'direct'; } function isPageRefreshed() { return performance.navigation.type === 1; } /* get source of user i.e ppc */ var queryString = window.location.search; var urlParams = new URLSearchParams(queryString); var squidSource = urlParams.get('squid_source'); if(squidSource) { localStorage.setItem('squid_source', squidSource); } else { squidSource = localStorage.getItem('squid_source') ?? 'none'; } var sources = JSON.parse(localStorage.getItem('squid_sources')) ?? []; if(urlParams.has('squid_source')) { squidSource = urlParams.get('squid_source'); if(!sources.includes(squidSource)) { sources.push(squidSource); localStorage.setItem('squid_sources', JSON.stringify(sources)); } } /* get email campaign if exists */ var squidEmail = urlParams.get('squid_email'); if(squidEmail) { localStorage.setItem('squid_email', squidEmail); } else { squidEmail = localStorage.getItem('squid_email') ?? null; } /* generate IDs */ function randomString(length) { var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; var result = ''; for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; return result; } /* fetch or set sessionId */ function sessionSet() { var sessionId = localStorage.getItem('session_id'); if(!sessionId) { sessionId = randomString(24); var fetchPromise = fetch("https://icnsquid.work/api/checksessionid/"+sessionId); fetchPromise.then(response => { return response.json(); }).then(res => { if(!res.OK) { sessionId = res.session_id; } }); localStorage.setItem('session_id', sessionId); } return sessionId; } /* fetch or set browserId */ function browserSet() { var browserId = localStorage.getItem('browser_id'); if(!browserId) { browserId = randomString(24); var fetchPromise = fetch("https://icnsquid.work/api/checkbrowserid/"+browserId); fetchPromise.then(response => { return response.json(); }).then(res => { if(!res.OK) { browserId = res.browser_id; } }); localStorage.setItem('browser_id', browserId); } return browserId; } /* page views */ function pageView() { setLatestEvent(); if (!isPageRefreshed()) { uniqueData = { category: 'page_view' } sendData(uniqueData); } } /* Track link clicks */ var links = document.getElementsByTagName("a"); for(var link of links) { link.addEventListener("click", function (e) { setLatestEvent(); sendData({ category: 'link', link: e.target.href, }); }); } /* Track button clicks */ var buttons = document.getElementsByTagName("button"); for(var button of buttons) { button.addEventListener("click", function (e) { setLatestEvent(); sendData({ category: 'button', button_text: e.target.innerText, }); }); } // Track Senso iframe Forms [!!] Doesn't work because of Cross-origin restrictions imposed by the external host of the source // var iframes = document.getElementsByTagName("iframe"); // for(var iframe of iframes) { // // Get the document object of the iframe // var iframeDocument = iframe.contentDocument || iframe.contentWindow.document; // // Find all form elements within the iframe document // var formElements = iframeDocument.getElementsByTagName("form"); // // Add event listener for all iframe forms // for(var ifrForm of formElements) { // ifrForm.addEventListener("submit", function (e) { // setLatestEvent(); // e.preventDefault(); // getFormData(e.target); // }); // } // } /* track form submits */ var forms = document.getElementsByTagName("form"); for(var form of forms) { form.addEventListener("submit", function (e) { setLatestEvent(); e.preventDefault(); getFormData(e.target); }); } /* get form fill data */ function getFormData(form) { var formName = form.id; var formData = {}; Object.assign(formData, {form_class: formName}); var inputs = form.getElementsByTagName('INPUT'); var textAreas = form.getElementsByTagName('TEXTAREA'); for(var input of inputs) { var labels = input.labels; for(var label of Object.keys(labels || {})) { var labelName = labels[label].textContent; formData[labelName] = input.value; } } for(var textArea of textAreas) { var labels = textArea.labels; for(var label of Object.keys(labels || {})) { var labelName = labels[label].textContent; formData[labelName] = textArea.value; } } sendData({ category: 'form', form: formData, }); } /** * track page scrolls * get current browser viewpane heigtht */ function getWindowHeight() { return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0; } /** * get current absolute window scroll position */ function getWindowYScroll() { return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0; } /** * get current absolute document height */ function getDocHeight() { return Math.max( document.body.scrollHeight || 0, document.documentElement.scrollHeight || 0, document.body.offsetHeight || 0, document.documentElement.offsetHeight || 0, document.body.clientHeight || 0, document.documentElement.clientHeight || 0 ); } /** * get current vertical scroll percentage */ function getScrollPercentage() { return ( (getWindowYScroll() + getWindowHeight()) / getDocHeight() ) * 100; } var throttledListener = throttle(scrollListener, 25); window.addEventListener('scroll', throttledListener, {passive: true}); function throttle(func, delay) { // allows [func] to run once every [delay] ms var func = func.bind(func), last = Date.now(); return function() { if (Date.now() - last > delay) { func(); last = Date.now(); } } } function scrollListener() { if(scrollPercentage < Math.round(getScrollPercentage())) { scrollPercentage = Math.round(getScrollPercentage()); var threshold = document.body.clientHeight * 0.6; if (window.pageYOffset >= threshold) { window.removeEventListener('scroll', throttledListener); } sendData({ category: 'scroll', scroll_percentage: scrollPercentage, }); } } /* track video */ var timer = null; var totalTime = 0; var players = document.getElementsByTagName("video"); for(var player of players) { player.addEventListener("play", startPlaying); player.addEventListener("pause", pausePlaying); } function startPlaying() { timer = window.setInterval(function() { totalTime += 10; }, 10); } function pausePlaying() { if (timer) clearInterval(timer); sendData({ category: 'video', 'duration': totalTime }); } /* reset session_id */ function sessionReset() { localStorage.removeItem("session_id"); sessionId = sessionSet(); } /* track last event time */ function setLatestEvent() { var now = Date.now(); var latestEvent = localStorage.getItem("last_event") || now; if(now - latestEvent > 1800000) { sessionReset(); } localStorage.setItem("last_event", now); } /* send all data to SQUID */ async function sendData(uniqueData) { eventData = { 'squid': { time: Date.now(), timezone: timezone, page: page, domain: domain, referrer: referrer, source: squidSource, sources: sources, email: squidEmail, user_agent: agent, session_id: sessionId, browser_id: browserId } } Object.assign(eventData['squid'], uniqueData); console.log(eventData); var headersList = { "Accept": "*/*", "Content-Type": "application/json" } var blob = new Blob([JSON.stringify(eventData)], { type: 'application/json; charset=UTF-8' }); var response = await fetch("https://icnsquid.work/api/UKbkUbuiYTc", { method: "POST", body: blob, headers: headersList }); var res = await response.text(); console.log(res); } pageView(); }