Files
2026-04-28 15:13:50 +02:00

3888 lines
159 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* global pysOptions */
! function ($, options) {
if (options.debug) {
console.log('PYS:', options);
}
var uniqueId = {};
let gtm_variables = {};
let gtm_datalayername = "dynamicVariable";
var domain = '';
if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) {
domain = getRootDomain(true);
}
/**
* Resolve parameter value based on mode (static or dynamic)
*
* @param {Object|string} param - Parameter object with { value, selector } or string value
* @param {string} key - Parameter key name
* @returns {string|null} - Resolved value
*/
function resolveParamValue(param, key = '') {
// 1⃣ null / undefined - skip this parameter
if (param === null || param === undefined) {
return null;
}
// 2⃣ Handle primitive types (string, number, boolean)
if (typeof param !== 'object') {
return param;
}
// 3⃣ Handle arrays - process each element recursively
if (Array.isArray(param)) {
return param.map(item => resolveParamValue(item, key));
}
// 4⃣ Check if this is a configuration object (has value/selector/dynamic/input_type)
const isConfigObject =
('value' in param || 'selector' in param || 'dynamic' in param || 'input_type' in param) &&
Object.keys(param).every(k =>
['value', 'selector', 'dynamic', 'input_type', 'name'].includes(k)
);
if (isConfigObject) {
// STATIC MODE: selector is empty or dynamic is false
const isStatic =
(!param.dynamic || param.dynamic === false) ||
(!param.selector || param.selector.trim() === '');
if (isStatic) {
let value = param.value ?? null;
// Apply numeric conversion if needed
if (param.input_type === "float" || param.input_type === "int") {
value = extractNumericValue(value, param.input_type === "int");
}
return value;
}
// DYNAMIC MODE: selector is present
try {
const el = document.querySelector(param.selector);
if (!el) {
return null;
}
let value =
el.value ||
el.innerText ||
el.textContent ||
el.getAttribute("content") ||
el.getAttribute("data-value") ||
null;
// Apply numeric conversion if needed
if (param.input_type === "float" || param.input_type === "int") {
value = extractNumericValue(value, param.input_type === "int");
}
return value;
} catch (e) {
return null;
}
}
// 5⃣ Plain object (like ecommerce data) - recursively process nested values
return Object.fromEntries(
Object.entries(param)
.map(([k, v]) => [k, resolveParamValue(v, k)])
.filter(([k, v]) => v !== null && v !== undefined)
);
}
function extractNumericValue(value, isInt = false) {
if (value === null || value === undefined) {
return null;
}
if (isInt) {
return parseInt(value);
}
return parseFloat(value);
}
var dummyPinterest = function () {
/**
* Public API
*/
return {
isEnabled: function () {},
disable: function () {},
loadPixel: function () {},
fireEvent: function (name, data) {
return false;
},
onCommentEvent: function () {},
onDownloadEvent: function (params) {},
onFormEvent: function (params) {},
onWooAddToCartOnButtonEvent: function (product_id) {},
onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {},
onWooRemoveFromCartEvent: function (cart_item_hash) {},
onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
onEddRemoveFromCartEvent: function (item) {},
onPageScroll: function (event) {},
onTime: function (event) {},
}
}();
var dummyBing = function () {
/**
* Public API
*/
return {
isEnabled: function () {},
disable: function () {},
loadPixel: function () {},
fireEvent: function (name, data) {
return false;
},
onAdSenseEvent: function () {},
onClickEvent: function (params) {},
onWatchVideo: function (params) {},
onCommentEvent: function () {},
onFormEvent: function (params) {},
onDownloadEvent: function (params) {},
onWooAddToCartOnButtonEvent: function (product_id) {},
onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {},
onWooRemoveFromCartEvent: function (cart_item_hash) {},
onWooAffiliateEvent: function (product_id) {},
onWooPayPalEvent: function () {},
onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
onEddRemoveFromCartEvent: function (item) {},
onPageScroll: function (event) {},
onTime: function (event) {},
}
}();
var dummyReddit = function () {
/**
* Public API
*/
return {
tag: function () {
return "reddit";
},
isEnabled: function () {},
disable: function () {},
loadPixel: function () {},
fireEvent: function ( name, data ) {
return false;
},
onAdSenseEvent: function ( event ) {},
onClickEvent: function ( params ) {},
onWatchVideo: function ( params ) {},
onCommentEvent: function ( event ) {},
onFormEvent: function ( params ) {},
onDownloadEvent: function ( params ) {},
onWooAddToCartOnButtonEvent: function ( product_id ) {},
onWooAddToCartOnSingleEvent: function ( product_id, qty, product_type, is_external, $form ) {},
onWooRemoveFromCartEvent: function ( cart_item_hash ) {},
onWooAffiliateEvent: function ( product_id ) {},
onWooPayPalEvent: function ( event ) {},
onEddAddToCartOnButtonEvent: function ( download_id, price_index, qty ) {},
onEddRemoveFromCartEvent: function ( item ) {},
onPageScroll: function ( event ) {},
onTime: function ( event ) {},
}
}();
var Utils = function (options) {
var Pinterest = dummyPinterest;
var Bing = dummyBing;
var Reddit = dummyReddit;
var gtag_loaded = false;
var gtm_loaded = false;
let isNewSession = checkSession();
var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
let dataLayerName = 'dataLayerPYS';
let GTMdataLayerName = 'dataLayer';
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
function getDomain(url) {
url = url.replace(/(https?:\/\/)?(www.)?/i, '');
if (url.indexOf('/') !== -1) {
return url.split('/')[0];
}
return url;
}
function loadPixels() {
if (!options.gdpr.all_disabled_by_api) {
if (!options.gdpr.facebook_disabled_by_api) {
Facebook.loadPixel();
}
if (!options.gdpr.analytics_disabled_by_api) {
Analytics.loadPixel();
}
if (!options.gdpr.analytics_disabled_by_api) {
GTM.loadPixel();
}
if (!options.gdpr.pinterest_disabled_by_api) {
Pinterest.loadPixel();
}
if (!options.gdpr.bing_disabled_by_api) {
Bing.loadPixel();
}
if (!options.gdpr.reddit_disabled_by_api) {
Reddit.loadPixel();
}
}
if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
Analytics.loadPixel();
}
}
}
function checkSession() {
if( Cookies.get('pys_start_session') === undefined ||
Cookies.get('pys_session_limit') === undefined) {
firstVisit = true;
return true
}
return false
}
function getTrafficSource() {
try {
let referrer = document.referrer.toString(),
source;
let direct = referrer.length === 0;
let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
let external = !direct && !internal;
if (external === false) {
source = 'direct';
} else {
source = referrer;
}
if (source !== 'direct') {
// leave only domain (Issue #70)
return getDomain(source);
} else {
return source;
}
} catch (e) {
console.error(e);
return 'direct';
}
}
/**
* Return query variables object with where property name is query variable
* and property value is query variable value.
*/
function getQueryVars() {
try {
var result = {},
tmp = [];
window.location.search
.substr(1)
.split("&")
.forEach(function (item) {
tmp = item.split('=');
if (tmp.length > 1) {
result[tmp[0]] = tmp[1];
}
});
return result;
} catch (e) {
console.error(e);
return {};
}
}
function getLandingPageValue() {
let name = "pys_landing_page"
if(options.visit_data_model === "last_visit") {
name = "last_pys_landing_page"
}
if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
return Cookies.get(name);
}
else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){
return options.tracking_analytics.TrafficLanding;
} else{
return "";
}
}
function getTrafficSourceValue() {
let name = "pysTrafficSource"
if(options.visit_data_model === "last_visit") {
name = "last_pysTrafficSource"
}
if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
return Cookies.get(name);
} else{
return "";
}
}
function getUTMId(useLast = false) {
try {
let cookiePrefix = 'pys_'
let terms = [];
if (useLast) {
cookiePrefix = 'last_pys_'
}
$.each(utmId, function (index, name) {
if (Cookies.get(cookiePrefix + name)) {
terms[name] = Cookies.get(cookiePrefix + name)
}
else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) {
terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name])
}
});
return terms;
} catch (e) {
console.error(e);
return [];
}
}
/**
* Return UTM terms from request query variables or from cookies.
*/
function getUTMs(useLast = false) {
try {
let cookiePrefix = 'pys_'
if(useLast) {
cookiePrefix = 'last_pys_'
}
let terms = [];
$.each(utmTerms, function (index, name) {
if (Cookies.get(cookiePrefix + name)) {
let value = Cookies.get(cookiePrefix + name);
terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
}
else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) {
terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name])
}
});
return terms;
} catch (e) {
console.error(e);
return [];
}
}
function getDateTime() {
var dateTime = new Array();
var date = new Date(),
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
months = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
],
hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
'08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
'17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
];
dateTime.push(hours[date.getHours()]);
dateTime.push(days[date.getDay()]);
dateTime.push(months[date.getMonth()]);
return dateTime;
}
function filterEmails(value) {
return validateEmail(value) ? undefined : value;
}
/**
* PUBLIC API
*/
return {
PRODUCT_SIMPLE : 0,
PRODUCT_VARIABLE : 1,
PRODUCT_BUNDLE : 2,
PRODUCT_GROUPED : 3,
utmTerms : utmTerms,
utmId : utmId,
fireEventForAllPixel:function(functionName,events){
if (events.hasOwnProperty(Facebook.tag()))
Facebook[functionName](events[Facebook.tag()]);
if (events.hasOwnProperty(Analytics.tag()))
Analytics[functionName](events[Analytics.tag()]);
if (events.hasOwnProperty(Pinterest.tag()))
Pinterest[functionName](events[Pinterest.tag()]);
if (events.hasOwnProperty(Bing.tag()))
Bing[functionName](events[Bing.tag()]);
if (events.hasOwnProperty(Reddit.tag()))
Reddit[functionName](events[Reddit.tag()]);
if (events.hasOwnProperty(GTM.tag()))
GTM[functionName](events[GTM.tag()]);
},
setupPinterestObject: function () {
Pinterest = window.pys.Pinterest || Pinterest;
return Pinterest;
},
setupBingObject: function () {
Bing = window.pys.Bing || Bing;
return Bing;
},
setupRedditObject: function () {
Reddit = window.pys.Reddit || Reddit;
return Reddit;
},
// Clone all object members to another and return it
copyProperties: function (from, to) {
for (var key in from) {
if("function" == typeof from[key]) {
continue;
}
to[key] = from[key];
}
return to;
},
manageCookies: function () {
if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) {
return;
}
}
let cm_consent_not_expressed = false;
if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) {
if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) {
cm_consent_not_expressed = true;
}
}
if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) {
let duration = options.last_visit_duration * 60000
var now = new Date();
now.setTime(now.getTime() + duration);
Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain })
Cookies.set('pys_start_session', true,{path: '/',domain: domain});
}
if (options.ajaxForServerEvent && !Cookies.get('pbid') && Facebook.isEnabled()) {
jQuery.ajax({
url: options.ajaxUrl,
dataType: 'json',
data: {
action: 'pys_get_pbid'
},
success: function (res) {
if (res.data && res.data.pbid != false && options.send_external_id) {
if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
var expires = parseInt(options.external_id_expire || 180);
Cookies.set('pbid', res.data.pbid, { expires: expires, path: '/',domain: domain });
}
if(options.hasOwnProperty('facebook')) {
options.facebook.advancedMatching = {
...options.facebook.advancedMatching, // spread current advancedMatching values
external_id: res.data.pbid
};
}
}
}
});
} else if (Cookies.get('pbid') && Facebook.isEnabled()){
if(Facebook.advancedMatching() && Facebook.advancedMatching().external_id && !(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
let expires = parseInt(options.external_id_expire || 180);
Cookies.set('pbid', Facebook.advancedMatching().external_id, { expires: expires, path: '/',domain: domain });
}
}
let expires = parseInt(options.cookie_duration); // days
let queryVars = getQueryVars();
let landing = window.location.href.split('?')[0];
try {
// save data for first visit
if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) {
if(!options.cookie.disabled_first_visit_cookie)
{
Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain });
}
else {
Cookies.remove('pys_first_visit')
}
if(!options.cookie.disabled_trafficsource_cookie)
{
Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
}
else {
Cookies.remove('pysTrafficSource')
}
if(!options.cookie.disabled_landing_page_cookie)
{
Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
}
else {
Cookies.remove('pys_landing_page')
}
if(!options.cookie.disabled_utmTerms_cookie)
{
$.each(utmTerms, function (index, name) {
if (queryVars.hasOwnProperty(name)) {
Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
} else {
Cookies.remove('pys_' + name)
}
});
}
else {
$.each(utmTerms, function (index, name) {
Cookies.remove('pys_' + name)
});
}
if(!options.cookie.disabled_utmId_cookie)
{
$.each(utmId,function(index,name) {
if (queryVars.hasOwnProperty(name)) {
Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
} else {
Cookies.remove('pys_' + name)
}
})
}
else {
$.each(utmId, function (index, name) {
Cookies.remove('pys_' + name)
});
}
}
// save data for last visit if it new session
if(isNewSession && (!options.cookie.disabled_all_cookie)) {
if(!options.cookie.disabled_trafficsource_cookie)
{
Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
}
else {
Cookies.remove('last_pysTrafficSource')
}
if(!options.cookie.disabled_landing_page_cookie)
{
Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
}
else {
Cookies.remove('last_pys_landing_page')
}
if(!options.cookie.disabled_utmTerms_cookie)
{
$.each(utmTerms, function (index, name) {
if (queryVars.hasOwnProperty(name)) {
Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
} else {
Cookies.remove('last_pys_' + name)
}
});
}
else {
$.each(utmTerms, function (index, name) {
Cookies.remove('last_pys_' + name)
});
}
if(!options.cookie.disabled_utmId_cookie)
{
$.each(utmId,function(index,name) {
if (queryVars.hasOwnProperty(name)) {
Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
} else {
Cookies.remove('last_pys_' + name)
}
})
}
else {
$.each(utmId, function (index, name) {
Cookies.remove('last_pys_' + name)
});
}
}
if(options.cookie.disabled_start_session_cookie) {
Cookies.remove('pys_start_session')
Cookies.remove('pys_session_limit')
}
if(options.cookie.disabled_all_cookie)
{
Cookies.remove('pys_first_visit')
Cookies.remove('pysTrafficSource')
Cookies.remove('pys_landing_page')
Cookies.remove('last_pys_landing_page')
Cookies.remove('last_pysTrafficSource')
Cookies.remove('pys_start_session')
Cookies.remove('pys_session_limit')
$.each(Utils.utmTerms, function (index, name) {
Cookies.remove('pys_' + name)
});
$.each(Utils.utmId,function(index,name) {
Cookies.remove('pys_' + name)
})
$.each(Utils.utmTerms, function (index, name) {
Cookies.remove('last_pys_' + name)
});
$.each(Utils.utmId,function(index,name) {
Cookies.remove('last_pys_' + name)
});
}
} catch (e) {
console.error(e);
}
},
/**
* Generate unique ID
*/
generateUniqueId : function (event) {
if(event.eventID.length == 0 || (event.type == "static" && options.ajaxForServerStaticEvent) || (event.type !== "static" && options.ajaxForServerEvent)) {
let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id;
if (!uniqueId.hasOwnProperty(idKey)) {
uniqueId[idKey] = pys_generate_token();
}
return uniqueId[idKey];
}
else if(event.eventID.length !== 0)
{
return event.eventID;
}
},
// Flatten object for sendBeacon compatibility
flattenObject: function (obj, prefix = '', res = {}) {
for (const [key, value] of Object.entries(obj)) {
const prefixedKey = prefix
? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
: key;
if (value !== null && typeof value === 'object' && !(value instanceof File)) {
this.flattenObject(value, prefixedKey, res);
} else {
res[prefixedKey] = value;
}
}
return res;
},
sendServerAjaxRequest : function(url, data) {
if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) {
// Use Facebook REST API
this.sendRestAPIRequest(data, 'facebook');
return;
}
// Check if sendBeacon is enabled and supported
if (options.useSendBeacon && navigator.sendBeacon) {
try {
// Flatten the data object for sendBeacon compatibility
const flattenedData = this.flattenObject(data);
const formData = new URLSearchParams();
// Convert flattened data to URLSearchParams
for (const [key, value] of Object.entries(flattenedData)) {
if (value !== null && value !== undefined) {
formData.append(key, value);
}
}
// Try to send using sendBeacon
const success = navigator.sendBeacon(url, formData);
if (success) {
return; // Successfully sent via sendBeacon
}
} catch (e) {
// If sendBeacon fails, fall back to jQuery.ajax
if (options.debug) {
console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e);
}
}
}
// Fallback to jQuery.ajax
jQuery.ajax( {
type: 'POST',
url: url,
data: data,
headers: {
'Cache-Control': 'no-cache'
},
success: function () {
},
} );
},
sendRestAPIRequest: function (data, platform) {
let restApiUrl;
// Get platform-specific REST API configuration
switch (platform) {
case 'facebook':
restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event';
break;
default:
console.error('PYS: Unknown platform for REST API:', platform);
this.sendAjaxFallback(data);
return;
}
// Prepare data for REST API
const restApiData = {
event: data.event,
data: JSON.stringify(data.data || {}),
ids: JSON.stringify(data.ids || []),
eventID: data.event_id || data.eventID || '',
woo_order: data.woo_order || '0',
edd_order: data.edd_order || '0'
};
// Try to send using sendBeacon first (if enabled)
if (options.useSendBeacon && navigator.sendBeacon) {
try {
const formData = new URLSearchParams();
for (const [key, value] of Object.entries(restApiData)) {
formData.append(key, value);
}
if (navigator.sendBeacon(restApiUrl, formData)) {
return;
}
} catch (e) {
// sendBeacon failed, continue to fetch
}
}
// Try to send using fetch with REST API
if (window.fetch) {
const headers = {
'Content-Type': 'application/json'
};
fetch(restApiUrl, {
method: 'POST',
headers: headers,
body: JSON.stringify(restApiData)
})
.then(response => {
if (!response.ok) {
throw new Error(platform + ' REST API request failed: ' + response.status);
}
})
.catch(error => {
// Fallback to AJAX if REST API fails
if (options.debug) {
console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error);
}
this.sendAjaxFallback(data);
});
} else {
// Fallback to AJAX if fetch is not supported
this.sendAjaxFallback(data);
}
},
// Fallback AJAX method
sendAjaxFallback: function (data) {
jQuery.ajax({
type: 'POST',
url: options.ajaxUrl,
data: data,
headers: {
'Cache-Control': 'no-cache'
},
success: function () {
},
});
},
// clone object
clone: function(obj) {
var copy;
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
if("function" == typeof obj[i]) {
continue;
}
copy[i] = Utils.clone(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) {
if("function" == typeof obj[attr]) {
continue;
}
copy[attr] = Utils.clone(obj[attr]);
}
}
return copy;
}
return obj;
},
// Returns array of elements with given tag name
getTagsAsArray: function (tag) {
return [].slice.call(document.getElementsByTagName(tag));
},
getRequestParams: function () {
return [];
},
/**
* CUSTOM EVENTS
*/
setupMouseOverClickEvents: function (eventId, triggers) {
// Non-default binding used to avoid situations when some code in external js
// stopping events propagation, eg. returns false, and our handler will never called
document.addEventListener('mouseover', function(event) {
var matchedElements = Array.from(document.querySelectorAll(triggers));
var clickedElement = event.target;
var closestMatch = clickedElement.closest(triggers);
if (matchedElements.includes(clickedElement) || closestMatch){
if (event.target.classList.contains('pys-mouse-over-' + eventId)) {
return true;
} else {
event.target.classList.add('pys-mouse-over-' + eventId);
}
Utils.fireTriggerEvent(eventId);
}
});
},
setupCSSClickEvents: function (eventId, triggers) {
// Non-default binding used to avoid situations when some code in external js
// stopping events propagation, eg. returns false, and our handler will never called
document.addEventListener('click', function(event) {
let matchedElements = Array.from(document.querySelectorAll(triggers)),
clickedElement = event.target,
closestMatch = clickedElement.closest(triggers);
if (matchedElements.includes(clickedElement) || closestMatch){
Utils.fireTriggerEvent(eventId);
}
}, true);
},
setupURLClickEvents: function () {
if( !options.triggerEventTypes.hasOwnProperty('url_click') ) {
return;
}
// Non-default binding used to avoid situations when some code in external js
// stopping events propagation, eg. returns false, and our handler will never called
$('a[data-pys-event-id]').onFirst('click', function (evt) {
$(this).attr('data-pys-event-id').split(',').forEach(function (eventId) {
eventId = parseInt(eventId);
if (isNaN(eventId) === false) {
Utils.fireTriggerEvent(eventId);
}
});
});
},
setupScrollPosEvents: function (eventId, triggers) {
var scrollPosThresholds = {},
docHeight = $(document).height() - $(window).height();
// convert % to absolute positions
$.each(triggers, function (index, scrollPos) {
// convert % to pixels
scrollPos = docHeight * scrollPos / 100;
scrollPos = Math.round(scrollPos);
scrollPosThresholds[scrollPos] = eventId;
});
$(document).on("scroll",function () {
var scrollPos = $(window).scrollTop();
$.each(scrollPosThresholds, function (threshold, eventId) {
// position has not reached yes
if (scrollPos <= threshold) {
return true;
}
// fire event only once
if (eventId === null) {
return true;
} else {
scrollPosThresholds[threshold] = null;
}
Utils.fireTriggerEvent(eventId);
});
});
},
setupCommentEvents : function (eventId,triggers) {
$('form.comment-form').on("submit",function () {
Utils.fireTriggerEvent(eventId);
});
},
/**
* Events
*/
fireTriggerEvent: function (eventId) {
if (!options.triggerEvents.hasOwnProperty(eventId)) {
return;
}
var event = {};
var events = options.triggerEvents[eventId];
if (events.hasOwnProperty('facebook')) {
event = Utils.getFormFilledData(events.facebook);
Facebook.fireEvent(event.name, event);
}
if (events.hasOwnProperty('ga')) {
event = Utils.getFormFilledData(events.ga);
Analytics.fireEvent(event.name, event);
}
if (events.hasOwnProperty('pinterest')) {
event = Utils.getFormFilledData(events.pinterest);
Pinterest.fireEvent(event.name, event);
}
if (events.hasOwnProperty('bing')) {
event = Utils.getFormFilledData(events.bing);
Bing.fireEvent(event.name, event);
}
if (events.hasOwnProperty('reddit')) {
event = Utils.getFormFilledData(events.reddit);
Reddit.fireEvent(event.name, event);
}
if (events.hasOwnProperty('gtm')) {
event = Utils.getFormFilledData(events.gtm);
GTM.fireEvent(event.name, event);
}
},
fireStaticEvents: function (pixel) {
if (options.staticEvents.hasOwnProperty(pixel)) {
$.each(options.staticEvents[pixel], function (eventName, events) {
$.each(events, function (index, eventData) {
eventData.fired = eventData.fired || false;
if (!eventData.fired) {
eventData = Utils.getFormFilledData(eventData);
var fired = false;
// fire event
if ('facebook' === pixel) {
fired = Facebook.fireEvent(eventData.name, eventData);
} else if ('ga' === pixel) {
fired = Analytics.fireEvent(eventData.name, eventData);
} else if ('pinterest' === pixel) {
fired = Pinterest.fireEvent(eventData.name, eventData);
} else if ('bing' === pixel) {
fired = Bing.fireEvent(eventData.name, eventData);
} else if ('gtm' === pixel) {
fired = GTM.fireEvent(eventData.name, eventData);
} else if ('reddit' === pixel) {
fired = Reddit.fireEvent(eventData.name, eventData);
}
// prevent event double event firing
eventData.fired = fired;
}
});
});
}
},
/**
* Load tag's JS
*
* @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
* @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
*/
loadGoogleTag: function (id) {
if (!gtag_loaded) {
let dataLayerName = this.dataLayerName;
if(options.hasOwnProperty('GATags')){
switch (options.GATags.ga_datalayer_type) {
case 'default':
dataLayerName = 'dataLayerPYS';
break;
case 'custom':
dataLayerName = options.GATags.ga_datalayer_name;
break;
default:
dataLayerName = 'dataLayer';
}
}
this.dataLayerName = dataLayerName;
(function (window, document, src) {
var a = document.createElement('script'),
m = document.getElementsByTagName('script')[0];
a.async = 1;
a.src = src;
m.parentNode.insertBefore(a, m);
})(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName);
window[dataLayerName] = window[dataLayerName] || [];
window.gtag = window.gtag || function gtag() {
window[dataLayerName].push(arguments);
};
if ( options.google_consent_mode ) {
let data = {};
data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
this.loadDefaultConsent( 'consent', 'default', data );
}
gtag('js', new Date());
gtag_loaded = true;
}
},
loadDefaultConsent: function() {
window[ this.dataLayerName ].push( arguments );
},
loadGTMScript: function (id = '') {
const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com';
const loader = options.gtm.gtm_container_identifier ?? 'gtm';
const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed
const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed
const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
window[ datalayer_name ] = window[ datalayer_name ] || [];
window.gtag = window.gtag || function gtag() {
window[ datalayer_name ].push( arguments );
};
if ( options.google_consent_mode ) {
let data = {};
data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
this.GTMdataLayerName = datalayer_name;
this.loadDefaultGTMConsent( 'consent', 'default', data );
}
(function(w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
const f = d.getElementsByTagName(s)[0];
const j = d.createElement(s);
const dl = l !== 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl;
if (gtm_auth && gtm_preview) {
j.src += '&gtm_auth=' + gtm_auth + '&gtm_preview=' + gtm_preview + '&gtm_cookies_win=x';
}
f.parentNode.insertBefore(j, f);
})(window, document, 'script', datalayer_name, id);
},
loadDefaultGTMConsent: function() {
window[ this.GTMdataLayerName ].push( arguments );
},
/**
* GDPR
*/
loadPixels: function () {
if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
// retrieves actual PYS GDPR filters values which allow to avoid cache issues
$.get({
url: options.ajaxUrl,
dataType: 'json',
data: {
action: 'pys_get_gdpr_filters_values'
},
success: function (res) {
if (res.success) {
options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
options.gdpr.reddit_disabled_by_api = res.data.reddit_disabled_by_api;
options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api;
options.cookie.disabled_all_cookie = res.data.disabled_all_cookie;
options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie;
options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie;
options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie;
options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie;
options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie;
options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie;
}
loadPixels();
}
});
} else {
loadPixels();
}
},
consentGiven: function (pixel) {
/**
* ConsentMagic
*/
if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
let test_prefix = CS_Data.test_prefix;
if (
( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) )
|| ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' )
|| ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode && pixel == 'reddit' )
|| ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' )
) {
if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) {
return true;
} else {
return false;
}
}
if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) {
return true;
} else if( pixel == 'reddit' && ( CS_Data.cs_script_cat?.reddit == 0 || CS_Data.cs_script_cat?.reddit == CS_Data.cs_necessary_cat_id ) ) {
return true;
}
let substring = "cs_enabled_cookie_term",
theCookies = document.cookie.split( ';' );
for ( let i = 1; i <= theCookies.length; i++ ) {
if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
return cs_cookie_val == 'yes';
} else if ( categoryCookie === CS_Data.cs_script_cat?.reddit && pixel == 'reddit' ) {
return cs_cookie_val == 'yes';
}
}
}
return false;
}
/**
* Real Cookie Banner
*/
if(options.gdpr.real_cookie_banner_integration_enabled) {
var consentApi = window.consentApi;
if (consentApi) {
switch (pixel) {
case "analytics":
return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
case "facebook":
return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
case "pinterest":
return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
default:
return true;
}
}
}
/**
* Cookiebot
*/
if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
if (options.gdpr[pixel + '_prior_consent_enabled']) {
if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) {
return true;
}
} else {
if (Cookiebot.consent[cookiebot_consent_category]) {
return true;
}
}
return false;
}
/**
* Cookie Notice
*/
if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
var cn_cookie = Cookies.get(cnArgs.cookieName);
if (options.gdpr[pixel + '_prior_consent_enabled']) {
if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
return true;
}
} else {
if (cn_cookie === 'true') {
return true;
}
}
return false;
}
/**
* Cookie Law Info
*/
if (options.gdpr.cookie_law_info_integration_enabled) {
var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
if (options.gdpr[pixel + '_prior_consent_enabled']) {
if (typeof cli_cookie === 'undefined') return true;
if (
cli_cookie &&
(cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
) {
if (getCookieYes('analytics') === 'yes') {
return true;
}
} else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
if (Cookies.get('viewed_cookie_policy') === 'yes') {
return true;
}
}
} else {
if (
cli_cookie &&
(cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
) {
if (getCookieYes('analytics') === 'yes') {
return true;
}
} else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
if (Cookies.get('viewed_cookie_policy') === 'yes') {
return true;
}
}
}
return false;
}
return true;
},
setupGdprCallbacks: function () {
/**
* ConsentMagic
*/
if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
let test_prefix = CS_Data.test_prefix,
cs_refresh_after_consent = false,
substring = "cs_enabled_cookie_term";
if (CS_Data.cs_refresh_after_consent == 1) {
cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
}
let consent_actions = function () {
let theCookies = document.cookie.split( ';' );
let consent = {
facebook: true,
ga: true,
google_ads: true,
tiktok: true,
bing: true,
pinterest: true,
gtm: true,
reddit: true,
};
for (let i = 1 ; i <= theCookies.length; i++) {
if (theCookies[i-1].indexOf(substring) !== -1) {
let categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_','');
categoryCookie = Number(categoryCookie.replace(/\D+/g,""));
let cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie);
if(cs_cookie_val == 'yes') {
if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) {
Facebook.loadPixel();
}
if ( categoryCookie === CS_Data.cs_script_cat.bing || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
Bing.loadPixel();
}
if (categoryCookie === CS_Data.cs_script_cat.analytics || (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1)) {
Analytics.loadPixel();
}
if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
Pinterest.loadPixel();
}
if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode ) ) {
Reddit.loadPixel();
}
} else {
if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) {
Facebook.disable();
consent.facebook = false;
}
if ( categoryCookie === CS_Data.cs_script_cat.bing && ( typeof CS_Data.cs_bing_consent_mode == "undefined" || !CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
Bing.disable();
consent.bing = false;
}
if (categoryCookie === CS_Data.cs_script_cat.analytics && (typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0)) {
Analytics.disable();
consent.ga = false;
consent.gtm = false;
}
if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
Pinterest.disable();
consent.pinterest = false;
}
if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) && ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || !CS_Data.cs_reddit_ldu_mode ) ) {
Reddit.disable();
consent.reddit = false;
}
}
if (Cookies.get('cs_enabled_advanced_matching') == 'yes') {
Facebook.loadPixel();
}
}
}
Utils.setupGDPRData( consent );
}
if (!cs_refresh_after_consent) {
consent_actions();
$(document).on('click','.cs_action_btn',function(e) {
e.preventDefault();
let consent = {
facebook: true,
ga: true,
bing: true,
pinterest: true,
gtm: true,
reddit: true,
};
let elm = $(this),
button_action = elm.attr('data-cs_action');
if(button_action === 'allow_all') {
Facebook.loadPixel();
Bing.loadPixel();
Analytics.loadPixel();
Pinterest.loadPixel();
Reddit.loadPixel();
consent.facebook = true;
consent.bing = true;
consent.ga = true;
consent.pinterest = true;
consent.reddit = true;
consent.gtm = true;
Utils.setupGDPRData( consent );
} else if ( button_action === 'disable_all' ) {
if ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) {
Facebook.disable();
consent.facebook = false;
}
if ( typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) {
Bing.disable();
consent.bing = false;
}
if ( CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined" ) {
Analytics.disable();
consent.ga = false;
consent.gtm = false;
}
if ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || CS_Data.cs_reddit_ldu_mode == 0 ) {
Reddit.disable();
consent.reddit = false;
}
Pinterest.disable();
consent.pinterest = false;
Utils.setupGDPRData( consent );
} else if ( button_action === 'cs_confirm' ) {
consent_actions();
}
});
}
}
/**
* Real Cookie Banner
*/
if(options.gdpr.real_cookie_banner_integration_enabled) {
let consentApi = window.consentApi;
if (consentApi) {
consentApi.consent("http", "_ga", "*")
.then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics));
consentApi.consent("http", "_fbp", "*")
.then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook));
consentApi.consent("http", "_pinterest_sess", ".pinterest.com")
.then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest));
consentApi.consent("http", "_uetsid", "*")
.then(Bing.loadPixel.bind(Bing), Bing.disable.bind(Bing));
let consent = {
facebook: true,
ga: true,
bing: true,
pinterest: true,
gtm: true,
};
if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) {
consent.ga = false;
consent.gtm = false;
}
if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) {
consent.facebook = false;
}
if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) {
consent.pinterest = false;
}
if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) {
consent.bing = false;
}
Utils.setupGDPRData( consent );
}
}
/**
* Cookiebot
*/
if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
window.addEventListener("CookiebotOnConsentReady", function() {
let consent = {
facebook: true,
ga: true,
bing: true,
pinterest: true,
gtm: true,
};
Utils.manageCookies();
if (Cookiebot.consent.marketing) {
Facebook.loadPixel();
Bing.loadPixel();
Pinterest.loadPixel();
consent.facebook = true;
consent.bing = true;
consent.pinterest = true;
}
if (Cookiebot.consent.statistics) {
Analytics.loadPixel();
consent.ga = true;
consent.gtm = true;
}
if (!Cookiebot.consent.marketing) {
Facebook.disable();
Pinterest.disable();
Bing.disable();
consent.facebook = false;
consent.bing = false;
consent.pinterest = false;
}
if (!Cookiebot.consent.statistics) {
Analytics.disable();
consent.ga = false;
consent.gtm = false;
}
Utils.setupGDPRData( consent );
});
}
/**
* Cookie Notice
*/
if (options.gdpr.cookie_notice_integration_enabled) {
$(document).onFirst('click', '.cn-set-cookie', function () {
let consent = {};
if ($(this).data('cookie-set') === 'accept') {
Facebook.loadPixel();
Analytics.loadPixel();
Pinterest.loadPixel();
Bing.loadPixel();
consent = {
facebook: true,
ga: true,
bing: true,
pinterest: true,
gtm: true,
};
} else {
Facebook.disable();
Analytics.disable();
Pinterest.disable();
Bing.disable();
consent = {
facebook: false,
ga: false,
bing: false,
pinterest: false,
gtm: false,
};
}
Utils.setupGDPRData( consent );
});
$(document).onFirst('click', '.cn-revoke-cookie', function () {
Facebook.disable();
Analytics.disable();
Pinterest.disable();
Bing.disable();
let consent = {
facebook: false,
ga: false,
bing: false,
pinterest: false,
gtm: false,
};
Utils.setupGDPRData( consent );
});
}
/**
* Cookie Law Info
*/
if (options.gdpr.cookie_law_info_integration_enabled) {
$(document).onFirst('click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () {
setTimeout(function (){
let cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
if (typeof cli_cookie !== 'undefined') {
if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) {
if (getCookieYes('analytics') === 'yes') {
Utils.manageCookies();
}
} else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
Utils.manageCookies();
}
}
},1000)
Facebook.loadPixel();
Analytics.loadPixel();
Pinterest.loadPixel();
Bing.loadPixel();
let consent = {
facebook: true,
ga: true,
bing: true,
pinterest: true,
gtm: true,
};
Utils.setupGDPRData( consent );
});
$(document).onFirst('click', '#cookie_action_close_header_reject, .cky-btn-reject', function () {
Facebook.disable();
Analytics.disable();
Pinterest.disable();
Bing.disable();
let consent = {
facebook: false,
ga: false,
bing: false,
pinterest: false,
gtm: false,
};
Utils.setupGDPRData( consent );
});
}
},
setupGDPRData: function ( consent ) {
consent = window.btoa( JSON.stringify( consent ) );
Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } );
},
/**
* DOWNLOAD DOCS
*/
getLinkExtension: function (link) {
// Remove anchor, query string and everything before last slash
link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
link = link.substring(link.lastIndexOf("/") + 1, link.length);
// If there's a period left in the URL, then there's a extension
if (link.length > 0 && link.indexOf('.') !== -1) {
link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period
return link;
} else {
return "";
}
},
getLinkFilename: function (link) {
// Remove anchor, query string and everything before last slash
link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
link = link.substring(link.lastIndexOf("/") + 1, link.length);
// If there's a period left in the URL, then there's a extension
if (link.length > 0 && link.indexOf('.') !== -1) {
return link;
} else {
return "";
}
},
/**
* Enrich
*/
isCheckoutPage: function () {
return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
$('body').hasClass('edd-checkout');
},
addCheckoutFields : function() {
var utm = "";
var utms = getUTMs()
$.each(utmTerms, function (index, name) {
if(index > 0) {
utm+="|";
}
utm+=name+":"+utms[name];
});
var utmIdList = "";
var utmsIds = getUTMId()
$.each(utmId, function (index, name) {
if(index > 0) {
utmIdList+="|";
}
utmIdList+=name+":"+utmsIds[name];
});
var utmIdListLast = "";
var utmsIdsLast = getUTMId(true)
$.each(utmId, function (index, name) {
if(index > 0) {
utmIdListLast+="|";
}
utmIdListLast+=name+":"+utmsIdsLast[name];
});
var utmLast = "";
var utmsLast = getUTMs(true)
$.each(utmTerms, function (index, name) {
if(index > 0) {
utmLast+="|";
}
utmLast+=name+":"+utmsLast[name];
});
var dateTime = getDateTime();
var landing = getLandingPageValue();
var lastLanding = getLandingPageValue();
var trafic = getTrafficSourceValue();
var lastTrafic = getTrafficSourceValue();
var $form = null;
if($('body').hasClass('woocommerce-checkout')) {
$form = $("form.woocommerce-checkout");
} else {
$form = $("#edd_purchase_form");
}
var inputs = {'pys_utm':utm,
'pys_utm_id':utmIdList,
'pys_browser_time':dateTime.join("|"),
'pys_landing':landing,
'pys_source':trafic,
'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
'last_pys_landing':lastLanding,
'last_pys_source':lastTrafic,
'last_pys_utm':utmLast,
'last_pys_utm_id':utmIdListLast,
}
Object.keys(inputs).forEach(function(key,index) {
$form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
});
},
getAdvancedFormData: function () {
let dataStr = Cookies.get("pys_advanced_form_data");
if(dataStr === undefined) {
return {'first_name':"",'last_name':"",'email':"",'phone':""};
} else {
return JSON.parse(dataStr);
}
},
getFormFilledData: function ( event ) {
// First, resolve static/dynamic parameters
if (event.params && Object.keys(event.params).length > 0) {
Object.entries(event.params).forEach(([key, value]) => {
// Resolve parameter value (static or dynamic)
const resolvedValue = resolveParamValue(value, key);
if (resolvedValue !== null) {
event.params[key] = resolvedValue;
}
else {
delete event.params[key];
}
});
}
return event;
}
};
}(options);
var Facebook = function (options) {
var defaultEventTypes = [
'PageView',
'ViewContent',
'Search',
'AddToCart',
'AddToWishlist',
'InitiateCheckout',
'AddPaymentInfo',
'Purchase',
'Lead',
'Subscribe',
'CustomizeProduct',
'FindLocation',
'StartTrial',
'SubmitApplication',
'Schedule',
'Contact',
'Donate'
];
var initialized = false;
var genereateFbp = function (){
return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp');
};
var genereateFbc = function (){
return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : ''
};
// fire server side event gdpr plugin installed
var isApiDisabled = options.gdpr.all_disabled_by_api ||
options.gdpr.facebook_disabled_by_api ||
options.gdpr.cookiebot_integration_enabled ||
options.gdpr.consent_magic_integration_enabled ||
options.gdpr.cookie_notice_integration_enabled ||
options.gdpr.cookie_law_info_integration_enabled;
/**
*
* @param allData
* @param params
* @returns {string | null}
*/
function sendFbServerEvent(allData,name,params) {
let eventId = null;
if(options.facebook.serverApiEnabled) {
if(allData.e_id === "woo_remove_from_cart") {// server event will sended from hook
Facebook.updateEventId(allData.name);
allData.eventID = Facebook.getEventId(allData.name);
} else {
// send event from server if they was bloc by gdpr or need send with delay
allData.eventID = Utils.generateUniqueId(allData);
if(Cookies.get('_fbp')){
params._fbp = Cookies.get('_fbp');
}
if(Cookies.get('_fbc')){
params._fbc = Cookies.get('_fbc');
}
if( options.ajaxForServerEvent || isApiDisabled ){
var json = {
action: 'pys_api_event',
pixel: 'facebook',
event: name,
data:params,
ids:options.facebook.pixelIds,
eventID:allData.eventID,
url:window.location.href,
ajax_event:options.ajax_event
};
if(allData.hasOwnProperty('woo_order')) {
json['woo_order'] = allData.woo_order;
}
if(allData.hasOwnProperty('edd_order')) {
json['edd_order'] = allData.edd_order;
}
if (allData.e_id === "automatic_event_internal_link" || allData.e_id === "automatic_event_outbound_link") {
setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), 500);
} else if (allData.type != 'static') {
Utils.sendServerAjaxRequest(options.ajaxUrl, json);
}
if ( ( allData.type == 'static' && options.ajaxForServerStaticEvent ) || ( allData.hasOwnProperty( 'ajaxFire' ) && allData.ajaxFire ) ) {
Utils.sendServerAjaxRequest( options.ajaxUrl, json );
}
}
}
delete params._fbp;
delete params._fbc;
eventId = allData.eventID
}
return eventId;
}
function fireEvent(name, allData) {
if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
return;
}
var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
var data = allData.params;
var params = {};
var arg = {};
Utils.copyProperties(data, params);
let eventId = sendFbServerEvent(allData,name,params)
if("hCR" === name) {
return;
}
if (options.debug) {
console.log('[Facebook] ' + name, params,"eventID",eventId);
}
if(eventId != null) {
arg.eventID = eventId;
}
fbq(actionType, name, params, arg);
}
/**
* Public API
*/
return {
tag: function() {
return "facebook";
},
isEnabled: function () {
return options.hasOwnProperty('facebook');
},
disable: function () {
initialized = false;
},
advancedMatching: function () {
if(options.facebook.advancedMatchingEnabled) {
let advancedMatchingForm = Utils.getAdvancedFormData();
let advancedMatching = {};
if(Object.keys(options.facebook.advancedMatching).length > 0) {
advancedMatching = options.facebook.advancedMatching;
}
if(!advancedMatching.hasOwnProperty("em")
&& advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) {
advancedMatching["em"] = advancedMatchingForm["email"];
}
if(!advancedMatching.hasOwnProperty("ph")
&& advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) {
advancedMatching["ph"] = advancedMatchingForm["phone"];
}
if(!advancedMatching.hasOwnProperty("fn")
&& advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) {
advancedMatching["fn"] = advancedMatchingForm["first_name"];
}
if(!advancedMatching.hasOwnProperty("ln")
&& advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) {
advancedMatching["ln"] = advancedMatchingForm["last_name"];
}
if(!advancedMatching.hasOwnProperty("external_id")){
if (Cookies.get('pbid') || (options.hasOwnProperty('pbid') && options.pbid)) {
advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : options.pbid;
}
}
else if(advancedMatching.external_id != Cookies.get('pbid'))
{
advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
}
if(Object.keys(advancedMatching).length > 0) {
return advancedMatching;
}
}
return false
},
/**
* Load pixel's JS
*/
loadPixel: function () {
if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
return;
}
!function (f, b, e, v, n, t, s) {
if (f.fbq) return;
n = f.fbq = function () {
n.callMethod ?
n.callMethod.apply(n, arguments) : n.queue.push(arguments)
};
if (!f._fbq) f._fbq = n;
n.push = n;
n.loaded = !0;
n.version = '2.0';
n.agent = 'dvpixelyoursite';
n.queue = [];
t = b.createElement(e);
t.async = !0;
t.src = v;
s = b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t, s)
}(window,
document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
let expires = parseInt(options.cookie_duration);
if(!Cookies.get('_fbp')) {
Cookies.set('_fbp',genereateFbp(), { expires: expires,path: '/',domain: domain });
}
if(getUrlParameter('fbclid')) {
Cookies.set('_fbc',genereateFbc(), { expires: expires,path: '/',domain: domain });
}
// initialize pixel
options.facebook.pixelIds.forEach(function (pixelId) {
if (options.facebook.removeMetadata) {
fbq('set', 'autoConfig', false, pixelId);
}
let advancedMatching = Facebook.advancedMatching();
if ( +options.facebook.meta_ldu === 1 ) {
fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 );
}
if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
if(!advancedMatching) {
fbq('init', pixelId);
} else {
var test_prefix = CS_Data.test_prefix;
var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
if (cs_advanced_matching == 'yes') {
fbq('init', pixelId, advancedMatching);
} else {
fbq('init', pixelId);
}
} else {
fbq('init', pixelId, advancedMatching);
}
}
} else {
if(!advancedMatching) {
fbq('init', pixelId);
} else {
fbq('init', pixelId, advancedMatching);
}
}
});
initialized = true;
Utils.fireStaticEvents('facebook');
},
fireEvent: function (name, data) {
if (!initialized || !this.isEnabled()) {
return false;
}
data.delay = data.delay || 0;
data.params = data.params || {};
if (data.delay === 0) {
fireEvent(name, data);
} else {
setTimeout(function (name, params) {
fireEvent(name, params);
}, data.delay * 1000, name, data);
}
return true;
},
onCommentEvent: function (event) {
this.fireEvent(event.name, event);
},
onDownloadEvent: function (event) {
this.fireEvent(event.name, event);
},
onFormEvent: function (event) {
this.fireEvent(event.name, event);
},
onWooAddToCartOnButtonEvent: function (product_id) {
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()];
window.pysWooProductData = window.pysWooProductData || [];
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
event = Utils.copyProperties(event, {})
Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params)
this.fireEvent(event.name, event);
}
}
},
onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
window.pysWooProductData = window.pysWooProductData || [];
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
product_id = parseInt($form.find('input[name="variation_id"]').val());
}
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params);
var groupValue = 0;
if(product_type === Utils.PRODUCT_GROUPED ) {
$form.find(".woocommerce-grouped-product-list .qty").each(function(index){
var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
var quantity = parseInt($(this).val());
if(isNaN(quantity)) {
quantity = 0;
}
var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
if(quantity == 0) {
event.params.content_ids.forEach(function(el,index,array) {
if(el == childItem.content_id) {
array.splice(index, 1);
}
});
}
if(event.params.hasOwnProperty('contents')) {
event.params.contents.forEach(function(el,index,array) {
if(el.id == childItem.content_id) {
if(quantity > 0){
el.quantity = quantity;
} else {
array.splice(index, 1);
}
}
});
}
groupValue += childItem.price * quantity;
});
if(groupValue == 0) return; // skip if no items selected
}
// maybe customize value option
if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
if(product_type === Utils.PRODUCT_GROUPED) {
event.params.value = groupValue;
} else if(product_type === Utils.PRODUCT_BUNDLE) {
var data = $(".bundle_form .bundle_data").data("bundle_form_data");
var items_sum = getBundlePriceOnSingleProduct(data);
event.params.value = (parseInt(data.base_price) + items_sum )* qty;
} else {
event.params.value = event.params.value * qty;
}
}
// only when non Facebook for WooCommerce logic used
if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
event.params.contents[0].quantity = qty;
}
this.fireEvent(event.name, event);
}
}
},
onWooRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
if (window.pysEddProductData.hasOwnProperty(download_id)) {
var index;
if (price_index) {
index = download_id + '_' + price_index;
} else {
index = download_id;
}
if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
// maybe customize value option
if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
event.params.value = event.params.value * qty;
}
// update contents qty param
var contents = event.params.contents;
contents[0].quantity = qty;
event.params.contents = contents;
this.fireEvent(event.name,event);
}
}
}
},
onEddRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onPageScroll: function (event) {
this.fireEvent(event.name, event);
},
onTime: function (event) {
this.fireEvent(event.name, event);
},
initEventIdCookies: function (key) {
var ids = {};
ids[key] = pys_generate_token(36)
Cookies.set('pys_fb_event_id', JSON.stringify(ids));
},
updateEventId:function(key) {
var cooData = Cookies.get("pys_fb_event_id")
if(cooData === undefined) {
this.initEventIdCookies(key);
} else {
var data = JSON.parse(cooData);
data[key] = pys_generate_token(36);
Cookies.set('pys_fb_event_id', JSON.stringify(data) );
}
},
getEventId:function (key) {
var data = Cookies.get("pys_fb_event_id");
if(data === undefined) {
this.initEventIdCookies(key);
data = Cookies.get("pys_fb_event_id");
}
return JSON.parse(data)[key];
},
sendFacebookRestAPIRequest: function(allData, name, params) {
if (typeof window.pysFacebookRest === 'undefined' || !window.pysFacebookRest.restApiUrl) {
return;
}
const restApiData = {
event: name,
data: JSON.stringify(params),
ids: allData.pixelIds || options.facebook.pixelIds,
eventID: allData.eventID,
woo_order: allData.woo_order || 0,
edd_order: allData.edd_order || 0
};
// Try sendBeacon first
if (navigator.sendBeacon) {
const formData = new FormData();
Object.keys(restApiData).forEach(key => {
if (Array.isArray(restApiData[key])) {
restApiData[key].forEach(value => {
formData.append(key + '[]', value);
});
} else {
formData.append(key, restApiData[key]);
}
});
if (navigator.sendBeacon(window.pysFacebookRest.restApiUrl, formData)) {
return;
}
}
// Fallback to fetch
fetch(window.pysFacebookRest.restApiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(restApiData)
}).catch(() => {
// Fallback to AJAX if fetch fails
this.sendAjaxFallback(allData, name, params);
});
},
sendAjaxFallback: function(allData, name, params) {
var json = {
action: 'pys_api_event',
pixel: 'facebook',
event: name,
data: params,
ids: allData.pixelIds || options.facebook.pixelIds,
eventID: allData.eventID,
url: window.location.href,
ajax_event: options.ajax_event
};
if (allData.hasOwnProperty('woo_order')) {
json['woo_order'] = allData.woo_order;
}
if (allData.hasOwnProperty('edd_order')) {
json['edd_order'] = allData.edd_order;
}
Utils.sendServerAjaxRequest(options.ajaxUrl, json);
},
};
}(options);
var Analytics = function (options) {
var initialized = false;
/**
* Fires event
*
* @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
* @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
* @link: https://developers.google.com/gtagjs/reference/event
* @link: https://developers.google.com/gtagjs/reference/parameter
*
* @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
*
* @param name
* @param data
*/
function fireEvent(name, data) {
if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
return;
}
var eventParams = Utils.copyProperties(data, {});
var _fireEvent = function (tracking_id,name,params) {
params['send_to'] = tracking_id;
if (options.debug) {
console.log('[Google Analytics #' + tracking_id + '] ' + name, params);
}
gtag('event', name, params);
};
options.ga.trackingIds.forEach(function (tracking_id) {
var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it
var params = mapParamsTov4(tracking_id,name,copyParams)
_fireEvent(tracking_id,name,params);
});
}
function mapParamsTov4(tag,name,param) {
//GA4 automatically collects a number of parameters for all events
delete param.landing_page;
// end
if(isv4(tag)) {
delete param.traffic_source;
delete param.event_category;
delete param.event_label;
delete param.ecomm_prodid;
delete param.ecomm_pagetype;
delete param.ecomm_totalvalue;
if(name === 'search') {
param['search'] = param.search_term;
delete param.search_term;
delete param.dynx_itemid;
delete param.dynx_pagetype;
delete param.dynx_totalvalue;
}
}
return param;
}
function isv4(tag) {
return tag.indexOf('G') === 0;
}
/**
* Public API
*/
return {
tag: function() {
return "ga";
},
isEnabled: function () {
return options.hasOwnProperty('ga');
},
disable: function () {
initialized = false;
},
loadPixel: function () {
if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
return;
}
Utils.loadGoogleTag(options.ga.trackingIds[0]);
var config = {};
// Cross-Domain tracking
if (options.ga.crossDomainEnabled) {
config.linker = {
accept_incoming: options.ga.crossDomainAcceptIncoming,
domains: options.ga.crossDomainDomains
};
}
var ids = options.ga.trackingIds;
// configure tracking ids
ids.forEach(function (trackingId,index) {
var obj = options.ga.isDebugEnabled;
var searchValue = "index_"+index;
var config_for_tag = Object.assign({}, options.config);
config_for_tag.debug_mode = false;
config_for_tag.send_page_view = !options.ga.custom_page_view_event;
for (var key in obj) {
if (obj.hasOwnProperty(key) && obj[key] === searchValue) {
config_for_tag.debug_mode = true;
break;
}
}
if(!config_for_tag.debug_mode)
{
delete config_for_tag.debug_mode;
}
if(isv4(trackingId)) {
if(options.ga.disableAdvertisingFeatures) {
config_for_tag.allow_google_signals = false
}
if(options.ga.disableAdvertisingPersonalization) {
config_for_tag.allow_ad_personalization_signals = false
}
}
if(options.ga.hasOwnProperty('additionalConfig')){
if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){
config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection;
}
}
if(options.ga.hasOwnProperty('serverContainerUrls')){
if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){
if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){
config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url;
}
if(options.ga.serverContainerUrls[trackingId].transport_url != ''){
config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url;
}
}
}
if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
if (options.gdpr['analytics_prior_consent_enabled']) {
if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
gtag('config', trackingId, config_for_tag);
}
} else {
if (Cookiebot.consent[cookiebot_consent_category]) {
gtag('config', trackingId, config_for_tag);
}
}
}
else
{
gtag('config', trackingId, config_for_tag);
}
});
initialized = true;
Utils.fireStaticEvents('ga');
},
fireEvent: function (name, data) {
if (!initialized || !this.isEnabled()) {
return false;
}
data.delay = data.delay || 0;
data.params = data.params || {};
data.params.eventID = Utils.generateUniqueId(data);
if (data.delay === 0) {
fireEvent(name, data.params);
} else {
setTimeout(function (name, params) {
fireEvent(name, params);
}, data.delay * 1000, name, data.params);
}
return true;
},
onCommentEvent: function (event) {
this.fireEvent(event.name, event);
},
onDownloadEvent: function (event) {
this.fireEvent(event.name, event);
},
onFormEvent: function (event) {
this.fireEvent(event.name, event);
},
onWooAddToCartOnButtonEvent: function (product_id) {
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
this.fireEvent(event.name, event);
}
}
},
onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
window.pysWooProductData = window.pysWooProductData || [];
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
product_id = parseInt($form.find('input[name="variation_id"]').val());
}
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
if(product_type === Utils.PRODUCT_GROUPED ) {
var groupValue = 0;
$form.find(".woocommerce-grouped-product-list .qty").each(function(index){
var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
var quantity = parseInt($(this).val());
if(isNaN(quantity)) {
quantity = 0;
}
var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
// update quantity
event.params.items.forEach(function(el,index,array) {
if(el.id == childItem.content_id) {
if(quantity > 0){
el.quantity = quantity;
} else {
array.splice(index, 1);
}
}
});
groupValue += childItem.price * quantity;
});
if(options.woo.addToCartOnButtonValueEnabled &&
options.woo.addToCartOnButtonValueOption !== 'global' &&
event.params.hasOwnProperty('ecomm_totalvalue')) {
event.params.ecomm_totalvalue = groupValue;
}
if(groupValue == 0) return; // skip if no items selected
} else {
// update items qty param
event.params.items[0].quantity = qty;
}
// maybe customize value option
if (options.woo.addToCartOnButtonValueEnabled &&
options.woo.addToCartOnButtonValueOption !== 'global' &&
product_type !== Utils.PRODUCT_GROUPED)
{
if(event.params.hasOwnProperty('ecomm_totalvalue')) {
event.params.ecomm_totalvalue = event.params.items[0].price * qty;
}
}
this.fireEvent(event.name, event);
}
}
},
onWooRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
if (window.pysEddProductData.hasOwnProperty(download_id)) {
var index;
if (price_index) {
index = download_id + '_' + price_index;
} else {
index = download_id;
}
if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
// update items qty param
event.params.items[0].quantity = qty;
this.fireEvent(event.name,event);
}
}
}
},
onEddRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onPageScroll: function (event) {
this.fireEvent(event.name, event);
},
onTime: function (event) {
this.fireEvent(event.name, event);
},
};
}(options);
var GTM = function (options) {
var initialized = false;
var datalayer_name = 'dataLayer';
/*
* @param name
* @param data
*/
function fireEvent(name, event) {
if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) {
return;
}
var eventParams = event.params;
var data = event.params;
var valuesArray = Object.values(event.trackingIds);
var ids = valuesArray;
Utils.copyProperties(Utils.getRequestParams(), eventParams);
var _fireEvent = function (tracking_id,name,params, event=null) {
var eventData = {};
var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0;
if(ContainerCodeHasTag) {
params['send_to'] = tracking_id;
}
else if(!options.gtm.gtm_just_data_layer){
return
}
if (params.hasOwnProperty('ecommerce')) {
eventData.ecommerce = params.ecommerce;
delete params.ecommerce;
}
var automatedParams = { ...params };
[params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]);
if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) {
eventData.automatedParameters = automatedParams;
}
// Move custom parameters to eventData
if (params.hasOwnProperty(params['manualName'])) {
eventData[params['manualName']] = params[params['manualName']];
delete params[params['manualName']];
}
['manualName','triggerType'].forEach(key => {
if (params.hasOwnProperty(key)) {
eventData[key] = params[key];
delete params[key];
}
});
eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
eventData.event = name;
if (options.debug) {
if (ContainerCodeHasTag){
console.log('[Google GTM #' + tracking_id + '] ' + name, eventData);
}
else {
console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData);
}
}
window[datalayer_name].push(eventData);
};
var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it
var params = mapParamsToGTM(ids,name,copyParams)
params.event_id = Utils.generateUniqueId(event);
_fireEvent(ids, name, params, event);
}
function normalizeEventName(eventName) {
var matches = {
ViewContent: 'view_item',
AddToCart: 'add_to_cart',
AddToWishList: 'add_to_wishlist',
InitiateCheckout: 'begin_checkout',
Purchase: 'purchase',
Lead: 'generate_lead',
CompleteRegistration: 'sign_up',
AddPaymentInfo: 'set_checkout_option'
};
return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
}
function mapParamsToGTM(tag,name,param) {
//GA4 automatically collects a number of parameters for all events
var hasGTM = false;
// end
if (Array.isArray(tag)) {
hasGTM = tag.some(function (element) {
return isGTM(element);
});
} else if(isGTM(tag)) {
// tag is a string and matches GTM
hasGTM = true;
}
if(hasGTM) {
delete param.event_category;
delete param.event_label;
delete param.analytics_storage;
delete param.ad_storage;
delete param.ad_user_data;
delete param.ad_personalization;
if(name === 'search') {
param['search'] = param.search_term;
delete param.search_term;
delete param.dynx_itemid;
delete param.dynx_pagetype;
delete param.dynx_totalvalue;
}
}
return param;
}
function isGTM(tag) {
return tag.indexOf('GTM') === 0;
}
/**
* Public API
*/
return {
tag: function() {
return "gtm";
},
isEnabled: function () {
return options.hasOwnProperty('gtm');
},
disable: function () {
initialized = false;
},
updateEnhancedConversionData : function () {
if (!initialized || !this.isEnabled()) {
return;
}
if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
var advanced = Utils.getAdvancedFormData();
if (Object.keys(advanced).length > 0) {
window[datalayer_name].push({'user_data' : advanced});
}
}
},
loadPixel: function () {
if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
return;
}
datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
for (var i = 0; i < options.gtm.trackingIds.length; i++) {
var trackingId = options.gtm.trackingIds[i];
if (!options.gtm.gtm_just_data_layer) {
console.log('[PYS] Google Tag Manager container code loaded');
Utils.loadGTMScript(trackingId);
break;
}
}
if(options.gtm.gtm_just_data_layer) {
console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!");
console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!");
if(options.gtm.trackingIds.length == 0){
Utils.loadGTMScript();
}
}
if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
var advanced = Utils.getAdvancedFormData();
if(Object.keys(advanced).length > 0){
window[datalayer_name].push({'user_data' : advanced});
}
}
var config = {};
if(options.user_id && options.user_id != 0) {
config.user_id = options.user_id;
}
// Cross-Domain tracking
var ids = options.gtm.trackingIds;
initialized = true;
Utils.fireStaticEvents('gtm');
},
fireEvent: function (name, data) {
if (!initialized || !this.isEnabled()) {
return false;
}
data.delay = data.delay || 0;
data.params = data.params || {};
if (data.delay === 0) {
fireEvent(name, data);
} else {
setTimeout(function (name, params) {
fireEvent(name, params);
}, data.delay * 1000, name, data);
}
return true;
},
onCommentEvent: function (event) {
this.fireEvent(event.name, event);
},
onDownloadEvent: function (event) {
this.fireEvent(event.name, event);
},
onFormEvent: function (event) {
this.fireEvent(event.name, event);
},
onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params)
this.fireEvent(event.name, event);
}
}
},
onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
window.pysWooProductData = window.pysWooProductData || [];
if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) {
product_id = parseInt($form.find('input[name="variation_id"]').val());
}
if (window.pysWooProductData.hasOwnProperty(product_id)) {
if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params);
params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params;
if(product_type === Utils.PRODUCT_GROUPED ) {
var groupValue = 0;
$form.find(".woocommerce-grouped-product-list .qty").each(function(index){
var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
var quantity = parseInt($(this).val());
if(isNaN(quantity)) {
quantity = 0;
}
var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId];
params.items.forEach(function(el,index,array) {
if(el.id == childItem.content_id) {
if(quantity > 0){
el.quantity = quantity;
el.price = childItem.price;
} else {
array.splice(index, 1);
}
}
});
groupValue += childItem.price * quantity;
});
if(options.woo.addToCartOnButtonValueEnabled &&
options.woo.addToCartOnButtonValueOption !== 'global' &&
params.hasOwnProperty('value')) {
params.value = groupValue;
}
if(groupValue == 0) return; // skip if no items selected
} else {
// update items qty param
params.items[0].quantity = qty;
}
// maybe customize value option
if (options.woo.addToCartOnButtonValueEnabled &&
options.woo.addToCartOnButtonValueOption !== 'global' &&
product_type !== Utils.PRODUCT_GROUPED)
{
if(params.hasOwnProperty('value')) {
params.value = params.items[0].price * qty;
}
}
this.fireEvent(event.name, event);
}
}
},
onWooRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
return;
var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
if (window.pysEddProductData.hasOwnProperty(download_id)) {
var index;
if (price_index) {
index = download_id + '_' + price_index;
} else {
index = download_id;
}
if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) {
Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params);
item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
// update items qty param
item.quantity = qty;
this.fireEvent(event.name,event);
}
}
}
},
onEddRemoveFromCartEvent: function (event) {
this.fireEvent(event.name, event);
},
onPageScroll: function (event) {
this.fireEvent(event.name, event);
},
onTime: function (event) {
this.fireEvent(event.name, event);
},
};
}(options);
var getPixelBySlag = function getPixelBySlag(slug) {
switch (slug) {
case "facebook": return window.pys.Facebook;
case "ga": return window.pys.Analytics;
case "gtm": return window.pys.GTM;
case "bing": return window.pys.Bing;
case "pinterest": return window.pys.Pinterest;
case "reddit": return window.pys.Reddit;
}
}
window.pys = window.pys || {};
window.pys.Facebook = Facebook;
window.pys.Analytics = Analytics;
window.pys.GTM = GTM;
window.pys.Utils = Utils;
window.pys.getPixelBySlag = getPixelBySlag;
// Export getPixelBySlag globally for backward compatibility
window.getPixelBySlag = getPixelBySlag;
$(document).ready(function () {
if($("#pys_late_event").length > 0) {
var dirAttr = $("#pys_late_event").attr("dir");
if (dirAttr) {
try {
var events = JSON.parse(dirAttr);
} catch (e) {
console.warn("Invalid JSON in pys_late_event dir attribute:", e);
}
} else {
console.warn("pys_late_event dir attribute is undefined or empty");
}
if (events) {
for (var key in events) {
var event = {};
event[events[key].e_id] = [events[key]];
if (options.staticEvents.hasOwnProperty(key)) {
Object.assign(options.staticEvents[key], event);
} else {
options.staticEvents[key] = event;
}
}
}
}
var Pinterest = Utils.setupPinterestObject();
var Bing = Utils.setupBingObject();
var Reddit = Utils.setupRedditObject();
if(options.hasOwnProperty('cookie'))
{
if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie)
{
Cookies.remove('pbid')
}
if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie)
{
Cookies.remove('pys_advanced_form_data')
}
if(options.cookie.disabled_landing_page_cookie || options.cookie.disabled_all_cookie)
{
Cookies.remove('pys_landing_page')
Cookies.remove('last_pys_landing_page')
}
if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie)
{
Cookies.remove('pysTrafficSource')
Cookies.remove('last_pysTrafficSource')
}
if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie)
{
Cookies.remove('pys_first_visit')
}
if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie)
{
$.each(Utils.utmTerms, function (index, name) {
Cookies.remove('pys_' + name)
});
$.each(Utils.utmTerms, function (index, name) {
Cookies.remove('last_pys_' + name)
});
}
if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie)
{
$.each(Utils.utmId,function(index,name) {
Cookies.remove('pys_' + name)
})
$.each(Utils.utmId,function(index,name) {
Cookies.remove('last_pys_' + name)
});
}
}
if (options.gdpr.cookie_law_info_integration_enabled) {
var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('viewed_cookie_policy');
if (typeof cli_cookie !== 'undefined') {
if (cli_cookie === Cookies.get('cookieyes-consent') && getCookieYes('analytics') == 'yes') {
Utils.manageCookies();
} else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
Utils.manageCookies();
}
}
}
if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) {
Utils.manageCookies();
} else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) {
Utils.manageCookies();
}
} else {
Utils.manageCookies();
}
Utils.setupGdprCallbacks();
// page scroll event
if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
) {
var singlePageScroll = function () {
var docHeight = $(document).height() - $(window).height();
var isFired = false;
if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
for(var i = 0;i<pixels.length;i++) {
var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
if(scroll < $(window).scrollTop()) {
if ( pixels[i] !== 'reddit') {
Utils.copyProperties( Utils.getRequestParams(), event.params );
}
getPixelBySlag( pixels[ i ] ).onPageScroll( event );
isFired = true
}
}
}
if(isFired) {
$(document).off("scroll",singlePageScroll);
}
}
$(document).on("scroll",singlePageScroll);
}
if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
setTimeout(function(){
for(var i = 0;i<pixels.length;i++) {
var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
if ( pixels[i] !== 'reddit') {
Utils.copyProperties(Utils.getRequestParams(), event.params);
}
getPixelBySlag(pixels[i]).onTime(event);
}
},time*1000);
}
// setup Click Event
if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
$(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
var $elem = $(this);
// Download
if(options.dynamicEvents.hasOwnProperty("automatic_event_download")
) {
var isFired = false;
if ($elem.is('a')) {
var href = $elem.attr('href');
if (typeof href !== "string") {
return;
}
href = href.trim();
var extension = Utils.getLinkExtension(href);
var track_download = false;
if (extension.length > 0) {
if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
for (var i = 0; i < pixels.length; i++) {
var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
var extensions = event.extensions;
if (extensions.includes(extension)) {
if( pixels[i] == "tiktok" || pixels[i] == "reddit" ) {
getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event);
} else {
if (options.enable_remove_download_url_param) {
href = href.split('?')[0];
}
event.params.download_url = href;
event.params.download_type = extension;
event.params.download_name = Utils.getLinkFilename(href);
getPixelBySlag(pixels[i]).onDownloadEvent(event);
}
isFired = true;
}
}
}
}
}
if(isFired) { // prevent duplicate events on the same element
return;
}
}
});
}
// setup Dynamic events
$.each(options.triggerEventTypes, function (triggerType, events) {
$.each(events, function (eventId, triggers) {
switch (triggerType) {
case 'url_click':
//@see: Utils.setupURLClickEvents()
break;
case 'css_click':
Utils.setupCSSClickEvents(eventId, triggers);
break;
case 'css_mouseover':
Utils.setupMouseOverClickEvents(eventId, triggers);
break;
case 'scroll_pos':
Utils.setupScrollPosEvents(eventId, triggers);
break;
case 'comment':
Utils.setupCommentEvents(eventId, triggers);
break;
}
});
});
// setup WooCommerce events
if (options.woo.enabled) {
// WooCommerce AddToCart
if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
&& options.woo.hasOwnProperty("addToCartCatchMethod")
&& options.woo.addToCartCatchMethod === "add_cart_js"
) {
// Loop, any kind of "simple" product, except external
$('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
var product_id = $(this).data('product_id');
if (typeof product_id !== 'undefined') {
if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")) {
var tmpEventID = pys_generate_token();
$.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
tag.eventID = tmpEventID;
});
}
if (typeof product_id !== 'undefined') {
Facebook.onWooAddToCartOnButtonEvent(product_id);
Analytics.onWooAddToCartOnButtonEvent(product_id);
GTM.onWooAddToCartOnButtonEvent(product_id);
Pinterest.onWooAddToCartOnButtonEvent(product_id);
Bing.onWooAddToCartOnButtonEvent(product_id);
Reddit.onWooAddToCartOnButtonEvent(product_id);
}
}
});
// Single Product
// tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
// $(document) not work
$('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
var $button = $(this);
if ($button.hasClass('disabled')) {
return;
}
var $form = $button.closest('form');
var product_type = Utils.PRODUCT_SIMPLE;
if ($form.length === 0) {
return ;
} else if ($form.hasClass('variations_form')) {
product_type = Utils.PRODUCT_VARIABLE;
} else if($form.hasClass('bundle_form')) {
product_type = Utils.PRODUCT_BUNDLE;
} else if($form.hasClass('grouped_form')) {
product_type = Utils.PRODUCT_GROUPED;
}
var product_id;
var qty;
if (product_type === Utils.PRODUCT_GROUPED) {
qty = 1;
product_id = parseInt($form.find('*[name="add-to-cart"]').val());
} else if (product_type === Utils.PRODUCT_VARIABLE) {
product_id = parseInt($form.find('*[name="add-to-cart"]').val());
var qtyTag = $form.find('input[name="quantity"]');
if(qtyTag.length <= 0) {
qtyTag = $form.find('select[name="quantity"]');
}
qty = parseInt(qtyTag.val());
} else {
product_id = parseInt($form.find('*[name="add-to-cart"]').val());
var qtyTag = $form.find('input[name="quantity"]');
if(qtyTag.length <= 0) {
qtyTag = $form.find('select[name="quantity"]');
}
qty = parseInt(qtyTag.val());
}
if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
var tmpEventID = pys_generate_token();
$.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
tag.eventID = tmpEventID;
});
}
Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
Reddit.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
});
}
// WooCommerce RemoveFromCart
if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
$('body').on('click', options.woo.removeFromCartSelector, function (e) {
var $a = $(e.currentTarget),
href = $a.attr('href');
// extract cart item hash from remove button URL
var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
results = regex.exec(href);
if (results !== null) {
var item_hash = results[1];
if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
}
}
});
}
}
// setup EDD events
if (options.edd.enabled) {
// EDD AddToCart
if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
$('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
var $button = $(this);
var $form = $button.closest('form');
var variable_price = $button.data('variablePrice'); // yes/no
var price_mode = $button.data('priceMode'); // single/multi
var ids = [];
var quantities = [];
var qty;
var id;
if (variable_price === 'yes' && price_mode === 'multi') {
id = $form.find('input[name="download_id"]').val();
// get selected variants
$.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
ids.push(id + '_' + $(el).val());
});
// get qty for selected variants
$.each(ids, function (i, variant_id) {
var variant_index = variant_id.split('_', 2);
qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
if (typeof qty !== 'undefined') {
quantities.push(qty);
} else {
quantities.push(1);
}
});
} else if (variable_price === 'yes' && price_mode === 'single') {
id = $form.find('input[name="download_id"]').val();
ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
qty = $form.find('input[name="edd_download_quantity"]').val();
if (typeof qty !== 'undefined') {
quantities.push(qty);
} else {
quantities.push(1);
}
} else {
ids.push($button.data('downloadId'));
qty = $form.find('input[name="edd_download_quantity"]').val();
if (typeof qty !== 'undefined') {
quantities.push(qty);
} else {
quantities.push(1);
}
}
// fire event for each download/variant
$.each(ids, function (i, download_id) {
var q = parseInt(quantities[i]);
var variant_index = download_id.toString().split('_', 2);
var price_index;
if (variant_index.length === 2) {
download_id = variant_index[0];
price_index = variant_index[1];
}
Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q);
Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
Reddit.onEddAddToCartOnButtonEvent(download_id, price_index, q);
});
});
}
// EDD RemoveFromCart
if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
$('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
var href = $(this).attr('href');
if(href) {
var key = href.substring(href.indexOf('=') + 1).charAt(0);
if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
var events = options.dynamicEvents.edd_remove_from_cart[key];
Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
}
}
});
}
}
// setup Comment Event
if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")
) {
$('form.comment-form').on("submit",function () {
if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
for (var i = 0; i < pixels.length; i++) {
var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]);
if ( pixels[i] !== 'reddit') {
Utils.copyProperties(Utils.getRequestParams(), event.params);
}
getPixelBySlag(pixels[i]).onCommentEvent(event);
}
}
});
}
// setup Form Event
if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
$(document).onFirst('submit', 'form', function (e) {
var $form = $(this);
// exclude WP forms
if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
return;
}
// exclude Woo forms
if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
$form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
return;
}
// exclude EDD forms
if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
return;
}
// exclude CF7 forms
if ($form.hasClass('wpcf7-form')) {
return;
}
// exclude Forminator forms
if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
return;
}
// exclude WPforms forms
if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
return;
}
// exclude Formidable forms
/*if ($form.hasClass('frm-show-form')) {
return;
}*/
// exclude Ninja Forms forms
if ($form.parent().hasClass('nf-form-layout')) {
return;
}
// exclude Fluent forms
if ($form.hasClass('frm-fluent-form')) {
return;
}
if(!options.enable_success_send_form) {
var params = {
form_id: $form.attr('id'),
form_class: $form.attr('class'),
text: $form.find('[type="submit"]').is('input') ?
$form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
};
if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
for (var i = 0; i < pixels.length; i++) {
var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
getPixelBySlag(pixels[i]).fireEvent(event.name, event);
} else {
Utils.copyProperties(params, event.params,)
Utils.copyProperties(Utils.getRequestParams(), event.params);
getPixelBySlag(pixels[i]).onFormEvent(event);
}
}
}
}
});
document.addEventListener( 'wpcf7mailsent', function( event ) {
var form_id = event.detail.contactFormId;
sendFormAction($(event.target), form_id);
}, false );
//Forminator
$(document).on( 'forminator:form:submit:success', function( event ){
var form_id = $(event.target).find('input[name="form_id"]').val();
sendFormAction($(event.target), form_id);
});
//WPForm
$('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => {
var form_id = $(event.target).attr('data-formid');
sendFormAction($(event.target), form_id);
})
$(document).on( 'frmFormComplete', function( event, form, response ) {
const form_id = $(form).find('input[name="form_id"]').val();
sendFormAction($(event.target), form_id);
});
// Ninja Forms
$(document).onFirst('nfFormSubmitResponse', function (event, data) {
const form_id = data.response.data.form_id;
sendFormAction($(event.target), form_id);
});
var fluentForms = $('form.frm-fluent-form');
fluentForms.each(function() {
var $form = $(this);
$form.on('fluentform_submission_success', function(event) {
var $formItem = $(this);
var form_id = $formItem.attr('data-form_id');
sendFormAction($(event.target), form_id);
});
});
}
// load pixel APIs
Utils.loadPixels();
// setup Enrich content
if(Utils.isCheckoutPage()) {
Utils.addCheckoutFields();
}
});
var sendFormAction = function (form_target, formId){
var params = {
form_id: formId,
text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
form_target.find('[type="submit"]').text()
};
if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
for (var i = 0; i < pixels.length; i++) {
var event = options.dynamicEvents.automatic_event_form[pixels[i]];
if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
getPixelBySlag(pixels[i]).fireEvent(event.name, event);
} else {
Utils.copyProperties(params, event.params)
Utils.copyProperties(Utils.getRequestParams(), event.params);
getPixelBySlag(pixels[i]).onFormEvent(event);
}
}
}
}
}(jQuery, pysOptions);
function pys_generate_token() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function getBundlePriceOnSingleProduct(data) {
var items_sum = 0;
jQuery(".bundle_form .bundled_product").each(function(index){
var id = jQuery(this).find(".cart").data("bundled_item_id");
var item_price = data.prices[id];
var item_quantity = jQuery(this).find(".bundled_qty").val();
if(!jQuery(this).hasClass("bundled_item_optional") ||
jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
items_sum += item_price*item_quantity;
}
});
return items_sum;
}
function getUrlParameter(sParam) {
var sPageURL = window.location.search.substring(1),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
}
}
return false;
};
function getCookieYes(key) {
const cookiesObj = document.cookie
.split(";")
.reduce((ac, cv) => {
const [k, v] = cv.split("=");
if (k && v) ac[k.trim()] = v;
return ac;
}, {});
const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"];
if (!consentCookie) return undefined;
const { [key]: value } = consentCookie
.split(",")
.reduce((obj, pair) => {
const [k, v] = pair.split(":");
if (k && v) obj[k] = v;
return obj;
}, {});
return value;
}
function getRootDomain(useSubdomain = false) {
const hostname = window.location.hostname; // Get the current hostname
// Check if tldjs is defined before using it
if (typeof tldjs === "undefined") {
console.warn("tldjs is not defined");
return hostname; // Return hostname as a fallback
}
const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain
// Return the root domain with or without a leading dot based on useSubdomain
return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname;
}