1/* global pysOptions */ 2 3 4! function ($, options) { 5 if (options.debug) { 6 console.log('PYS:', options); 7 } 8 var uniqueId = {}; 9 10 let gtm_variables = {}; 11 let gtm_datalayername = "dynamicVariable"; 12 13 var domain = ''; 14 if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) { 15 domain = getRootDomain(true); 16 } 17 18 var dummyPinterest = function () { 19 20 /** 21 * Public API 22 */ 23 return { 24 isEnabled: function () {}, 25 disable: function () {}, 26 loadPixel: function () {}, 27 fireEvent: function (name, data) { 28 return false; 29 }, 30 onCommentEvent: function () {}, 31 onDownloadEvent: function (params) {}, 32 onFormEvent: function (params) {}, 33 onWooAddToCartOnButtonEvent: function (product_id) {}, 34 onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {}, 35 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 36 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 37 onEddRemoveFromCartEvent: function (item) {}, 38 onPageScroll: function (event) {}, 39 onTime: function (event) {}, 40 41 } 42 43 }(); 44 45 var dummyBing = function () { 46 47 /** 48 * Public API 49 */ 50 return { 51 isEnabled: function () {}, 52 disable: function () {}, 53 loadPixel: function () {}, 54 fireEvent: function (name, data) { 55 return false; 56 }, 57 onAdSenseEvent: function () {}, 58 onClickEvent: function (params) {}, 59 onWatchVideo: function (params) {}, 60 onCommentEvent: function () {}, 61 onFormEvent: function (params) {}, 62 onDownloadEvent: function (params) {}, 63 onWooAddToCartOnButtonEvent: function (product_id) {}, 64 onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {}, 65 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 66 onWooAffiliateEvent: function (product_id) {}, 67 onWooPayPalEvent: function () {}, 68 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 69 onEddRemoveFromCartEvent: function (item) {}, 70 onPageScroll: function (event) {}, 71 onTime: function (event) {}, 72 } 73 74 }(); 75 76 var dummyReddit = function () { 77 /** 78 * Public API 79 */ 80 return { 81 tag: function () { 82 return "reddit"; 83 }, 84 isEnabled: function () {}, 85 disable: function () {}, 86 loadPixel: function () {}, 87 fireEvent: function ( name, data ) { 88 return false; 89 }, 90 onAdSenseEvent: function ( event ) {}, 91 onClickEvent: function ( params ) {}, 92 onWatchVideo: function ( params ) {}, 93 onCommentEvent: function ( event ) {}, 94 onFormEvent: function ( params ) {}, 95 onDownloadEvent: function ( params ) {}, 96 onWooAddToCartOnButtonEvent: function ( product_id ) {}, 97 onWooAddToCartOnSingleEvent: function ( product_id, qty, product_type, is_external, $form ) {}, 98 onWooRemoveFromCartEvent: function ( cart_item_hash ) {}, 99 onWooAffiliateEvent: function ( product_id ) {}, 100 onWooPayPalEvent: function ( event ) {}, 101 onEddAddToCartOnButtonEvent: function ( download_id, price_index, qty ) {}, 102 onEddRemoveFromCartEvent: function ( item ) {}, 103 onPageScroll: function ( event ) {}, 104 onTime: function ( event ) {}, 105 } 106 }(); 107 108 109 var Utils = function (options) { 110 111 var Pinterest = dummyPinterest; 112 113 var Bing = dummyBing; 114 115 var Reddit = dummyReddit; 116 117 var gtag_loaded = false; 118 119 var gtm_loaded = false; 120 121 let isNewSession = checkSession(); 122 123 var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; 124 125 var utmId = ['fbadid', 'gadid', 'padid', 'bingid']; 126 127 let dataLayerName = 'dataLayerPYS'; 128 129 let GTMdataLayerName = 'dataLayer'; 130 131 function validateEmail(email) { 132 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,}))$/; 133 return re.test(email); 134 } 135 function getDomain(url) { 136 137 url = url.replace(/(https?:\/\/)?(www.)?/i, ''); 138 139 if (url.indexOf('/') !== -1) { 140 return url.split('/')[0]; 141 } 142 143 return url; 144 } 145 function loadPixels() { 146 147 if (!options.gdpr.all_disabled_by_api) { 148 149 if (!options.gdpr.facebook_disabled_by_api) { 150 Facebook.loadPixel(); 151 } 152 153 if (!options.gdpr.analytics_disabled_by_api) { 154 Analytics.loadPixel(); 155 } 156 157 if (!options.gdpr.analytics_disabled_by_api) { 158 GTM.loadPixel(); 159 } 160 161 if (!options.gdpr.pinterest_disabled_by_api) { 162 Pinterest.loadPixel(); 163 } 164 165 if (!options.gdpr.bing_disabled_by_api) { 166 Bing.loadPixel(); 167 } 168 169 if (!options.gdpr.reddit_disabled_by_api) { 170 Reddit.loadPixel(); 171 } 172 } 173 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 174 if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) { 175 Analytics.loadPixel(); 176 } 177 } 178 179 } 180 181 function checkSession() { 182 if( Cookies.get('pys_start_session') === undefined || 183 Cookies.get('pys_session_limit') === undefined) { 184 firstVisit = true; 185 return true 186 } 187 return false 188 189 } 190 191 function getTrafficSource() { 192 193 try { 194 195 let referrer = document.referrer.toString(), 196 source; 197 198 let direct = referrer.length === 0; 199 let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0; 200 let external = !direct && !internal; 201 202 if (external === false) { 203 source = 'direct'; 204 } else { 205 source = referrer; 206 } 207 208 if (source !== 'direct') { 209 // leave only domain (Issue #70) 210 return getDomain(source); 211 } else { 212 return source; 213 } 214 215 } catch (e) { 216 console.error(e); 217 return 'direct'; 218 } 219 220 } 221 222 /** 223 * Return query variables object with where property name is query variable 224 * and property value is query variable value. 225 */ 226 function getQueryVars() { 227 228 try { 229 230 var result = {}, 231 tmp = []; 232 233 window.location.search 234 .substr(1) 235 .split("&") 236 .forEach(function (item) { 237 238 tmp = item.split('='); 239 240 if (tmp.length > 1) { 241 result[tmp[0]] = tmp[1]; 242 } 243 244 }); 245 246 return result; 247 248 } catch (e) { 249 console.error(e); 250 return {}; 251 } 252 253 } 254 255 256 function getLandingPageValue() { 257 let name = "pys_landing_page" 258 if(options.visit_data_model === "last_visit") { 259 name = "last_pys_landing_page" 260 } 261 if(Cookies.get(name) && Cookies.get(name) !== "undefined") { 262 return Cookies.get(name); 263 } 264 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){ 265 return options.tracking_analytics.TrafficLanding; 266 } else{ 267 return ""; 268 } 269 } 270 function getTrafficSourceValue() { 271 let name = "pysTrafficSource" 272 if(options.visit_data_model === "last_visit") { 273 name = "last_pysTrafficSource" 274 } 275 if(Cookies.get(name) && Cookies.get(name) !== "undefined") { 276 return Cookies.get(name); 277 } 278 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficSource){ 279 return options.tracking_analytics.TrafficSource; 280 } else{ 281 return ""; 282 } 283 } 284 285 function getUTMId(useLast = false) { 286 try { 287 let cookiePrefix = 'pys_' 288 let terms = []; 289 if (useLast) { 290 cookiePrefix = 'last_pys_' 291 } 292 $.each(utmId, function (index, name) { 293 if (Cookies.get(cookiePrefix + name)) { 294 terms[name] = Cookies.get(cookiePrefix + name) 295 } 296 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) { 297 terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name]) 298 } 299 }); 300 return terms; 301 } catch (e) { 302 console.error(e); 303 return []; 304 } 305 } 306 /** 307 * Return UTM terms from request query variables or from cookies. 308 */ 309 function getUTMs(useLast = false) { 310 311 try { 312 let cookiePrefix = 'pys_' 313 if(useLast) { 314 cookiePrefix = 'last_pys_' 315 } 316 let terms = []; 317 $.each(utmTerms, function (index, name) { 318 if (Cookies.get(cookiePrefix + name)) { 319 let value = Cookies.get(cookiePrefix + name); 320 terms[name] = filterEmails(value); // do not allow email in request params (Issue #70) 321 } 322 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) { 323 terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name]) 324 } 325 }); 326 327 return terms; 328 329 } catch (e) { 330 console.error(e); 331 return []; 332 } 333 334 } 335 336 function getDateTime() { 337 var dateTime = new Array(); 338 var date = new Date(), 339 days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 340 months = ['January', 'February', 'March', 'April', 'May', 'June', 341 'July', 'August', 'September', 'October', 'November', 'December' 342 ], 343 hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08', 344 '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17', 345 '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24' 346 ]; 347 dateTime.push(hours[date.getHours()]); 348 dateTime.push(days[date.getDay()]); 349 dateTime.push(months[date.getMonth()]); 350 return dateTime; 351 } 352 353 function filterEmails(value) { 354 return validateEmail(value) ? undefined : value; 355 } 356 357 /** 358 * PUBLIC API 359 */ 360 return { 361 PRODUCT_SIMPLE : 0, 362 PRODUCT_VARIABLE : 1, 363 PRODUCT_BUNDLE : 2, 364 PRODUCT_GROUPED : 3, 365 utmTerms : utmTerms, 366 utmId : utmId, 367 fireEventForAllPixel:function(functionName,events){ 368 if (events.hasOwnProperty(Facebook.tag())) 369 Facebook[functionName](events[Facebook.tag()]); 370 if (events.hasOwnProperty(Analytics.tag())) 371 Analytics[functionName](events[Analytics.tag()]); 372 if (events.hasOwnProperty(Pinterest.tag())) 373 Pinterest[functionName](events[Pinterest.tag()]); 374 if (events.hasOwnProperty(Bing.tag())) 375 Bing[functionName](events[Bing.tag()]); 376 if (events.hasOwnProperty(Reddit.tag())) 377 Reddit[functionName](events[Reddit.tag()]); 378 379 if (events.hasOwnProperty(GTM.tag())) 380 GTM[functionName](events[GTM.tag()]); 381 }, 382 383 setupPinterestObject: function () { 384 Pinterest = window.pys.Pinterest || Pinterest; 385 return Pinterest; 386 }, 387 388 setupBingObject: function () { 389 Bing = window.pys.Bing || Bing; 390 return Bing; 391 }, 392 393 setupRedditObject: function () { 394 Reddit = window.pys.Reddit || Reddit; 395 return Reddit; 396 }, 397 398 // Clone all object members to another and return it 399 copyProperties: function (from, to) { 400 for (var key in from) { 401 if("function" == typeof from[key]) { 402 continue; 403 } 404 to[key] = from[key]; 405 } 406 return to; 407 }, 408 409 manageCookies: function () { 410 411 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 412 if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) { 413 return; 414 } 415 } 416 let cm_consent_not_expressed = false;
417 if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) { 418 if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) { 419 cm_consent_not_expressed = true; 420 } 421 } 422 423 if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) { 424 let duration = options.last_visit_duration * 60000 425 var now = new Date(); 426 now.setTime(now.getTime() + duration); 427 Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain }) 428 Cookies.set('pys_start_session', true,{path: '/',domain: domain}); 429 } 430 431 if (options.ajaxForServerEvent && !Cookies.get('pbid') && Facebook.isEnabled()) { 432 jQuery.ajax({ 433 url: options.ajaxUrl, 434 dataType: 'json', 435 data: { 436 action: 'pys_get_pbid' 437 }, 438 success: function (res) { 439 if (res.data && res.data.pbid != false && options.send_external_id) { 440 if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){ 441 var expires = parseInt(options.external_id_expire || 180); 442 Cookies.set('pbid', res.data.pbid, { expires: expires, path: '/',domain: domain }); 443 } 444 445 if(options.hasOwnProperty('facebook')) { 446 options.facebook.advancedMatching = { 447 ...options.facebook.advancedMatching, // spread current advancedMatching values 448 external_id: res.data.pbid 449 }; 450 } 451 } 452 } 453 }); 454 } else if (Cookies.get('pbid') && Facebook.isEnabled()){ 455 if(Facebook.advancedMatching() && Facebook.advancedMatching().external_id && !(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){ 456 let expires = parseInt(options.external_id_expire || 180); 457 Cookies.set('pbid', Facebook.advancedMatching().external_id, { expires: expires, path: '/',domain: domain }); 458 } 459 } 460 461 let expires = parseInt(options.cookie_duration); // days 462 let queryVars = getQueryVars(); 463 let landing = window.location.href.split('?')[0]; 464 try { 465 // save data for first visit 466 if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) { 467 468 if(!options.cookie.disabled_first_visit_cookie) 469 { 470 Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain }); 471 } 472 else { 473 Cookies.remove('pys_first_visit') 474 } 475 476 if(!options.cookie.disabled_trafficsource_cookie) 477 { 478 Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain }); 479 } 480 else { 481 Cookies.remove('pysTrafficSource') 482 } 483 484 if(!options.cookie.disabled_landing_page_cookie) 485 { 486 Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain }); 487 } 488 else { 489 Cookies.remove('pys_landing_page') 490 } 491 492 if(!options.cookie.disabled_utmTerms_cookie) 493 { 494 $.each(utmTerms, function (index, name) { 495 if (queryVars.hasOwnProperty(name)) { 496 Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 497 } else { 498 Cookies.remove('pys_' + name) 499 } 500 }); 501 } 502 else { 503 $.each(utmTerms, function (index, name) { 504 Cookies.remove('pys_' + name) 505 }); 506 } 507 508 if(!options.cookie.disabled_utmId_cookie) 509 { 510 $.each(utmId,function(index,name) { 511 if (queryVars.hasOwnProperty(name)) { 512 Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 513 } else { 514 Cookies.remove('pys_' + name) 515 } 516 }) 517 } 518 else { 519 $.each(utmId, function (index, name) { 520 Cookies.remove('pys_' + name) 521 }); 522 } 523 } 524 525 // save data for last visit if it new session 526 if(isNewSession && (!options.cookie.disabled_all_cookie)) { 527 if(!options.cookie.disabled_trafficsource_cookie) 528 { 529 Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain }); 530 } 531 else { 532 Cookies.remove('last_pysTrafficSource') 533 } 534 535 if(!options.cookie.disabled_landing_page_cookie) 536 { 537 Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain }); 538 } 539 else { 540 Cookies.remove('last_pys_landing_page') 541 } 542 543 if(!options.cookie.disabled_utmTerms_cookie) 544 { 545 $.each(utmTerms, function (index, name) { 546 if (queryVars.hasOwnProperty(name)) { 547 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 548 } else { 549 Cookies.remove('last_pys_' + name) 550 } 551 }); 552 } 553 else { 554 $.each(utmTerms, function (index, name) { 555 Cookies.remove('last_pys_' + name) 556 }); 557 } 558 559 if(!options.cookie.disabled_utmId_cookie) 560 { 561 $.each(utmId,function(index,name) { 562 if (queryVars.hasOwnProperty(name)) { 563 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 564 } else { 565 Cookies.remove('last_pys_' + name) 566 } 567 }) 568 } 569 else { 570 $.each(utmId, function (index, name) { 571 Cookies.remove('last_pys_' + name) 572 }); 573 } 574 575 } 576 if(options.cookie.disabled_start_session_cookie) { 577 Cookies.remove('pys_start_session') 578 Cookies.remove('pys_session_limit') 579 } 580 if(options.cookie.disabled_all_cookie) 581 { 582 Cookies.remove('pys_first_visit') 583 Cookies.remove('pysTrafficSource') 584 Cookies.remove('pys_landing_page') 585 Cookies.remove('last_pys_landing_page') 586 Cookies.remove('last_pysTrafficSource') 587 Cookies.remove('pys_start_session') 588 Cookies.remove('pys_session_limit') 589 $.each(Utils.utmTerms, function (index, name) { 590 Cookies.remove('pys_' + name) 591 }); 592 $.each(Utils.utmId,function(index,name) { 593 Cookies.remove('pys_' + name) 594 }) 595 $.each(Utils.utmTerms, function (index, name) { 596 Cookies.remove('last_pys_' + name) 597 }); 598 $.each(Utils.utmId,function(index,name) { 599 Cookies.remove('last_pys_' + name) 600 }); 601 } 602 } catch (e) { 603 console.error(e); 604 } 605 }, 606 /** 607 * Generate unique ID 608 */ 609 generateUniqueId : function (event) { 610 if(event.eventID.length == 0 || (event.type == "static" && options.ajaxForServerStaticEvent) || (event.type !== "static" && options.ajaxForServerEvent)) { 611 let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id; 612 if (!uniqueId.hasOwnProperty(idKey)) { 613 uniqueId[idKey] = pys_generate_token(); 614 } 615 return uniqueId[idKey]; 616 } 617 else if(event.eventID.length !== 0) 618 { 619 return event.eventID; 620 } 621 }, 622 623 // Flatten object for sendBeacon compatibility 624 flattenObject: function (obj, prefix = '', res = {}) { 625 for (const [key, value] of Object.entries(obj)) { 626 const prefixedKey = prefix 627 ? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
628 : key; 629 if (value !== null && typeof value === 'object' && !(value instanceof File)) { 630 this.flattenObject(value, prefixedKey, res); 631 } else { 632 res[prefixedKey] = value; 633 } 634 } 635 return res; 636 }, 637 638 sendServerAjaxRequest : function(url, data) { 639 if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) { 640 // Use Facebook REST API 641 this.sendRestAPIRequest(data, 'facebook'); 642 return; 643 } 644 645 // Check if sendBeacon is enabled and supported 646 if (options.useSendBeacon && navigator.sendBeacon) { 647 try { 648 // Flatten the data object for sendBeacon compatibility 649 const flattenedData = this.flattenObject(data); 650 const formData = new URLSearchParams(); 651 652 // Convert flattened data to URLSearchParams 653 for (const [key, value] of Object.entries(flattenedData)) { 654 if (value !== null && value !== undefined) { 655 formData.append(key, value); 656 } 657 } 658 659 // Try to send using sendBeacon 660 const success = navigator.sendBeacon(url, formData); 661 if (success) { 662 return; // Successfully sent via sendBeacon 663 } 664 } catch (e) { 665 // If sendBeacon fails, fall back to jQuery.ajax 666 if (options.debug) { 667 console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e); 668 } 669 } 670 } 671 672 // Fallback to jQuery.ajax 673 jQuery.ajax( { 674 type: 'POST', 675 url: url, 676 data: data, 677 headers: { 678 'Cache-Control': 'no-cache' 679 }, 680 success: function () { 681 }, 682 } ); 683 }, 684 685 sendRestAPIRequest: function (data, platform) { 686 let restApiUrl; 687 688 // Get platform-specific REST API configuration 689 switch (platform) { 690 case 'facebook': 691 restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event'; 692 break; 693 default: 694 console.error('PYS: Unknown platform for REST API:', platform); 695 this.sendAjaxFallback(data); 696 return; 697 } 698 699 // Prepare data for REST API 700 const restApiData = { 701 event: data.event, 702 data: JSON.stringify(data.data || {}), 703 ids: JSON.stringify(data.ids || []), 704 eventID: data.event_id || data.eventID || '', 705 woo_order: data.woo_order || '0', 706 edd_order: data.edd_order || '0' 707 }; 708 709 // Try to send using sendBeacon first (if enabled) 710 if (options.useSendBeacon && navigator.sendBeacon) { 711 try { 712 const formData = new URLSearchParams(); 713 for (const [key, value] of Object.entries(restApiData)) { 714 formData.append(key, value); 715 } 716 717 if (navigator.sendBeacon(restApiUrl, formData)) { 718 return; 719 } 720 } catch (e) { 721 // sendBeacon failed, continue to fetch 722 } 723 } 724 725 // Try to send using fetch with REST API 726 if (window.fetch) { 727 const headers = { 728 'Content-Type': 'application/json' 729 }; 730 731 fetch(restApiUrl, { 732 method: 'POST', 733 headers: headers, 734 body: JSON.stringify(restApiData) 735 }) 736 .then(response => { 737 if (!response.ok) {
738 throw new Error(platform + ' REST API request failed: ' + response.status); 739 } 740 }) 741 .catch(error => { 742 // Fallback to AJAX if REST API fails 743 if (options.debug) { 744 console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error); 745 } 746 this.sendAjaxFallback(data); 747 }); 748 } else { 749 // Fallback to AJAX if fetch is not supported 750 this.sendAjaxFallback(data); 751 } 752 }, 753 754 755 756 // Fallback AJAX method 757 sendAjaxFallback: function (data) { 758 jQuery.ajax({ 759 type: 'POST', 760 url: options.ajaxUrl, 761 data: data, 762 headers: { 763 'Cache-Control': 'no-cache' 764 }, 765 success: function () { 766 }, 767 }); 768 }, 769 // clone object 770 clone: function(obj) { 771 var copy; 772 773 // Handle the 3 simple types, and null or undefined 774 if (null == obj || "object" != typeof obj) return obj; 775 776 // Handle Date 777 if (obj instanceof Date) { 778 copy = new Date(); 779 copy.setTime(obj.getTime()); 780 return copy; 781 } 782 783 // Handle Array 784 if (obj instanceof Array) { 785 copy = []; 786 for (var i = 0, len = obj.length; i < len; i++) { 787 if("function" == typeof obj[i]) { 788 continue; 789 } 790 copy[i] = Utils.clone(obj[i]); 791 } 792 return copy; 793 } 794 795 // Handle Object 796 if (obj instanceof Object) { 797 copy = {}; 798 for (var attr in obj) { 799 if (obj.hasOwnProperty(attr)) { 800 if("function" == typeof obj[attr]) { 801 continue; 802 } 803 copy[attr] = Utils.clone(obj[attr]); 804 } 805 } 806 return copy; 807 } 808 809 return obj; 810 }, 811 812 // Returns array of elements with given tag name 813 getTagsAsArray: function (tag) { 814 return [].slice.call(document.getElementsByTagName(tag)); 815 }, 816
817 getRequestParams: function () { 818 return []; 819 }, 820 821 /** 822 * CUSTOM EVENTS 823 */ 824 825 setupMouseOverClickEvents: function (eventId, triggers) { 826 827 // Non-default binding used to avoid situations when some code in external js 828 // stopping events propagation, eg. returns false, and our handler will never called 829 document.addEventListener('mouseover', function(event) { 830 var matchedElements = Array.from(document.querySelectorAll(triggers)); 831 var clickedElement = event.target; 832 var closestMatch = clickedElement.closest(triggers); 833 if (matchedElements.includes(clickedElement) || closestMatch){ 834 if (event.target.classList.contains('pys-mouse-over-' + eventId)) { 835 return true; 836 } else { 837 event.target.classList.add('pys-mouse-over-' + eventId); 838 } 839 840 Utils.fireTriggerEvent(eventId); 841 } 842 }); 843 844 }, 845 846 setupCSSClickEvents: function (eventId, triggers) { 847 // Non-default binding used to avoid situations when some code in external js 848 // stopping events propagation, eg. returns false, and our handler will never called 849 document.addEventListener('click', function(event) { 850 let matchedElements = Array.from(document.querySelectorAll(triggers)), 851 clickedElement = event.target, 852 closestMatch = clickedElement.closest(triggers); 853 854 if (matchedElements.includes(clickedElement) || closestMatch){ 855 Utils.fireTriggerEvent(eventId); 856 } 857 }, true); 858 }, 859 860 setupURLClickEvents: function () { 861 862 if( !options.triggerEventTypes.hasOwnProperty('url_click') ) { 863 return; 864 } 865 // Non-default binding used to avoid situations when some code in external js 866 // stopping events propagation, eg. returns false, and our handler will never called 867 $('a[data-pys-event-id]').onFirst('click', function (evt) { 868 869 $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) { 870 871 eventId = parseInt(eventId); 872 873 if (isNaN(eventId) === false) { 874 Utils.fireTriggerEvent(eventId); 875 } 876 877 }); 878 879 }); 880 881 882 }, 883 884 setupScrollPosEvents: function (eventId, triggers) { 885 886 var scrollPosThresholds = {}, 887 docHeight = $(document).height() - $(window).height(); 888 889 // convert % to absolute positions 890 $.each(triggers, function (index, scrollPos) { 891 892 // convert % to pixels 893 scrollPos = docHeight * scrollPos / 100; 894 scrollPos = Math.round(scrollPos); 895 896 scrollPosThresholds[scrollPos] = eventId; 897 898 }); 899 900 $(document).on("scroll",function () { 901 902 var scrollPos = $(window).scrollTop(); 903 904 $.each(scrollPosThresholds, function (threshold, eventId) { 905 906 // position has not reached yes 907 if (scrollPos <= threshold) { 908 return true; 909 } 910 911 // fire event only once 912 if (eventId === null) { 913 return true; 914 } else { 915 scrollPosThresholds[threshold] = null; 916 } 917 918 Utils.fireTriggerEvent(eventId); 919 920 }); 921 922 }); 923 924 925 }, 926 setupCommentEvents : function (eventId,triggers) { 927 $('form.comment-form').on("submit",function () { 928 Utils.fireTriggerEvent(eventId); 929 }); 930 }, 931 932 /** 933 * Events 934 */ 935 936 fireTriggerEvent: function (eventId) { 937 938 if (!options.triggerEvents.hasOwnProperty(eventId)) { 939 return; 940 } 941 942 var event = {}; 943 var events = options.triggerEvents[eventId]; 944 945 if (events.hasOwnProperty('facebook')) { 946 event = events.facebook; 947 Facebook.fireEvent(event.name, event); 948 } 949 950 if (events.hasOwnProperty('ga')) { 951 event = events.ga; 952 Analytics.fireEvent(event.name, event); 953 } 954 955 if (events.hasOwnProperty('pinterest')) { 956 event = events.pinterest; 957 Pinterest.fireEvent(event.name, event); 958 } 959 960 if (events.hasOwnProperty('bing')) { 961 event = events.bing; 962 Bing.fireEvent(event.name, event); 963 } 964 965 if (events.hasOwnProperty('reddit')) { 966 event = events.reddit;
967 if(Utils.isEventInTimeWindow(event.name,event,"dyn_reddit_"+eventId)) { 968 event = Utils.getFormFilledData(event); 969 Reddit.fireEvent(event.name, event); 970 } 971 } 972 973 if (events.hasOwnProperty('gtm')) { 974 event = events.gtm; 975 GTM.fireEvent(event.name, event); 976 } 977 }, 978 979 fireStaticEvents: function (pixel) { 980 981 if (options.staticEvents.hasOwnProperty(pixel)) { 982 983 $.each(options.staticEvents[pixel], function (eventName, events) { 984 $.each(events, function (index, eventData) { 985 986 eventData.fired = eventData.fired || false; 987 988 if (!eventData.fired) { 989 990 var fired = false; 991 992 // fire event 993 if ('facebook' === pixel) { 994 fired = Facebook.fireEvent(eventData.name, eventData); 995 } else if ('ga' === pixel) { 996 fired = Analytics.fireEvent(eventData.name, eventData); 997 } else if ('pinterest' === pixel) { 998 fired = Pinterest.fireEvent(eventData.name, eventData); 999 } else if ('bing' === pixel) { 1000 fired = Bing.fireEvent(eventData.name, eventData); 1001 } else if ('gtm' === pixel) { 1002 fired = GTM.fireEvent(eventData.name, eventData); 1003 } else if ('reddit' === pixel) { 1004 fired = Reddit.fireEvent(eventData.name, eventData); 1005 } 1006 1007 // prevent event double event firing 1008 eventData.fired = fired; 1009 1010 } 1011 1012 }); 1013 }); 1014 1015 } 1016 1017 }, 1018 1019 /** 1020 * Load tag's JS 1021 * 1022 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/ 1023 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 1024 */ 1025 loadGoogleTag: function (id) { 1026 1027 if (!gtag_loaded) { 1028 let dataLayerName = this.dataLayerName; 1029 if(options.hasOwnProperty('GATags')){ 1030 switch (options.GATags.ga_datalayer_type) { 1031 case 'default': 1032 dataLayerName = 'dataLayerPYS'; 1033 break; 1034 case 'custom': 1035 dataLayerName = options.GATags.ga_datalayer_name; 1036 break; 1037 default: 1038 dataLayerName = 'dataLayer'; 1039 } 1040 } 1041 this.dataLayerName = dataLayerName; 1042 (function (window, document, src) { 1043 var a = document.createElement('script'), 1044 m = document.getElementsByTagName('script')[0]; 1045 a.async = 1; 1046 a.src = src; 1047 m.parentNode.insertBefore(a, m); 1048 })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName); 1049 1050 window[dataLayerName] = window[dataLayerName] || []; 1051 window.gtag = window.gtag || function gtag() { 1052 window[dataLayerName].push(arguments); 1053 }; 1054 1055 if ( options.google_consent_mode ) { 1056 let data = {}; 1057 data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted'; 1058 data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted'; 1059 data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted'; 1060 data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted'; 1061 1062 this.loadDefaultConsent( 'consent', 'default', data ); 1063 } 1064 1065 gtag('js', new Date()); 1066 gtag_loaded = true; 1067 1068 } 1069 1070 }, 1071 1072 loadDefaultConsent: function() { 1073 window[ this.dataLayerName ].push( arguments ); 1074 }, 1075 1076 loadGTMScript: function (id = '') { 1077 const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com'; 1078 const loader = options.gtm.gtm_container_identifier ?? 'gtm'; 1079 const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed 1080 const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed 1081 const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 1082 1083 window[ datalayer_name ] = window[ datalayer_name ] || []; 1084 window.gtag = window.gtag || function gtag() { 1085 window[ datalayer_name ].push( arguments ); 1086 }; 1087 1088 if ( options.google_consent_mode ) { 1089 let data = {};
1090 data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted'; 1091 data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted'; 1092 data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted'; 1093 data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted'; 1094 1095 this.GTMdataLayerName = datalayer_name; 1096 this.loadDefaultGTMConsent( 'consent', 'default', data ); 1097 } 1098 1099 (function(w, d, s, l, i) { 1100 w[l] = w[l] || []; 1101 w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); 1102 const f = d.getElementsByTagName(s)[0]; 1103 const j = d.createElement(s); 1104 const dl = l !== 'dataLayer' ? '&l=' + l : ''; 1105 j.async = true; 1106 j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl; 1107 if (gtm_auth && gtm_preview) { 1108 j.src += '>m_auth=' + gtm_auth + '>m_preview=' + gtm_preview + '>m_cookies_win=x'; 1109 } 1110 f.parentNode.insertBefore(j, f); 1111 })(window, document, 'script', datalayer_name, id); 1112 1113 }, 1114 1115 loadDefaultGTMConsent: function() { 1116 window[ this.GTMdataLayerName ].push( arguments ); 1117 }, 1118 1119 /** 1120 * GDPR 1121 */ 1122 1123 loadPixels: function () { 1124 1125 if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) { 1126 1127 // retrieves actual PYS GDPR filters values which allow to avoid cache issues 1128 $.get({ 1129 url: options.ajaxUrl, 1130 dataType: 'json', 1131 data: { 1132 action: 'pys_get_gdpr_filters_values' 1133 }, 1134 success: function (res) { 1135 1136 if (res.success) { 1137 1138 options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api; 1139 options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api; 1140 options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api; 1141 options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api; 1142 options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api; 1143 options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api; 1144 options.gdpr.reddit_disabled_by_api = res.data.reddit_disabled_by_api; 1145 1146 options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api; 1147 options.cookie.disabled_all_cookie = res.data.disabled_all_cookie; 1148 options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie; 1149 options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie; 1150 options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie; 1151 options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie; 1152 options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie; 1153 options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie; 1154 } 1155 1156 loadPixels(); 1157 1158 } 1159 }); 1160 1161 } else { 1162 loadPixels(); 1163 } 1164 1165 }, 1166 1167 consentGiven: function (pixel) { 1168 1169 /** 1170 * ConsentMagic 1171 */ 1172 if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 1173 1174 let test_prefix = CS_Data.test_prefix; 1175 if ( 1176 ( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) ) 1177 || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' ) 1178 || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode && pixel == 'reddit' ) 1179 || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' ) 1180 ) { 1181 if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) { 1182 return true; 1183 } else { 1184 return false;
1185 } 1186 } 1187 1188 if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) { 1189 return true; 1190 } else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) { 1191 return true; 1192 } else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) { 1193 return true; 1194 } else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) { 1195 return true; 1196 } else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) { 1197 return true; 1198 } else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) { 1199 return true; 1200 } else if( pixel == 'reddit' && ( CS_Data.cs_script_cat?.reddit == 0 || CS_Data.cs_script_cat?.reddit == CS_Data.cs_necessary_cat_id ) ) { 1201 return true; 1202 } 1203 1204 let substring = "cs_enabled_cookie_term", 1205 theCookies = document.cookie.split( ';' ); 1206 1207 for ( let i = 1; i <= theCookies.length; i++ ) { 1208 if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) { 1209 let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' ); 1210 categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) ); 1211 let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie ); 1212 1213 if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) { 1214 return cs_cookie_val == 'yes'; 1215 } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) { 1216 return cs_cookie_val == 'yes'; 1217 } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) { 1218 return cs_cookie_val == 'yes'; 1219 } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) { 1220 return cs_cookie_val == 'yes'; 1221 } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) { 1222 return cs_cookie_val == 'yes'; 1223 } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) { 1224 return cs_cookie_val == 'yes'; 1225 } else if ( categoryCookie === CS_Data.cs_script_cat?.reddit && pixel == 'reddit' ) { 1226 return cs_cookie_val == 'yes'; 1227 } 1228 } 1229 } 1230 1231 return false; 1232 } 1233 1234 /** 1235 * Real Cookie Banner 1236 */ 1237 if(options.gdpr.real_cookie_banner_integration_enabled) { 1238 var consentApi = window.consentApi; 1239 if (consentApi) { 1240 switch (pixel) { 1241 case "analytics": 1242 return consentApi.consentSync("http", "_ga", "*").cookieOptIn; 1243 case "facebook": 1244 return consentApi.consentSync("http", "_fbp", "*").cookieOptIn; 1245 case "pinterest": 1246 return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn; 1247 default: 1248 return true; 1249 } 1250 } 1251 } 1252 1253 /** 1254 * Cookiebot 1255 */ 1256 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1257 1258 var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category']; 1259 1260 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1261 if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) { 1262 return true; 1263 } 1264 } else { 1265 if (Cookiebot.consent[cookiebot_consent_category]) { 1266 return true; 1267 } 1268 } 1269 1270 return false;
1271 1272 } 1273 1274 /** 1275 * Cookie Notice 1276 */ 1277 if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') { 1278 1279 var cn_cookie = Cookies.get(cnArgs.cookieName); 1280 1281 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1282 if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') { 1283 return true; 1284 } 1285 } else { 1286 if (cn_cookie === 'true') { 1287 return true; 1288 } 1289 } 1290 1291 return false; 1292 1293 } 1294 1295 /** 1296 * Cookie Law Info 1297 */ 1298 if (options.gdpr.cookie_law_info_integration_enabled) { 1299 var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy'); 1300 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1301 if (typeof cli_cookie === 'undefined') return true; 1302 if ( 1303 cli_cookie && 1304 (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) 1305 ) { 1306 if (getCookieYes('analytics') === 'yes') { 1307 return true; 1308 } 1309 } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) { 1310 if (Cookies.get('viewed_cookie_policy') === 'yes') { 1311 return true; 1312 } 1313 } 1314 } else { 1315 if ( 1316 cli_cookie && 1317 (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) 1318 ) { 1319 if (getCookieYes('analytics') === 'yes') { 1320 return true; 1321 } 1322 } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) { 1323 if (Cookies.get('viewed_cookie_policy') === 'yes') { 1324 return true; 1325 } 1326 } 1327 } 1328 return false; 1329 } 1330 1331 return true; 1332 1333 }, 1334 1335 setupGdprCallbacks: function () { 1336 /** 1337 * ConsentMagic 1338 */ 1339 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 1340 let test_prefix = CS_Data.test_prefix, 1341 cs_refresh_after_consent = false, 1342 substring = "cs_enabled_cookie_term"; 1343 1344 if (CS_Data.cs_refresh_after_consent == 1) { 1345 cs_refresh_after_consent = CS_Data.cs_refresh_after_consent; 1346 } 1347 1348 let consent_actions = function () { 1349 let theCookies = document.cookie.split( ';' ); 1350 1351 let consent = { 1352 facebook: true, 1353 ga: true, 1354 google_ads: true, 1355 tiktok: true, 1356 bing: true, 1357 pinterest: true, 1358 gtm: true, 1359 reddit: true, 1360 }; 1361 1362 for (let i = 1 ; i <= theCookies.length; i++) { 1363 if (theCookies[i-1].indexOf(substring) !== -1) { 1364 let categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_',''); 1365 categoryCookie = Number(categoryCookie.replace(/\D+/g,"")); 1366 let cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie); 1367 if(cs_cookie_val == 'yes') { 1368 if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) { 1369 Facebook.loadPixel(); 1370 } 1371 1372 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 ) ) { 1373 Bing.loadPixel(); 1374 } 1375 1376 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)
1376) { 1377 1378 Analytics.loadPixel(); 1379 } 1380 1381 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 1382 Pinterest.loadPixel(); 1383 } 1384 1385 if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode ) ) { 1386 Reddit.loadPixel(); 1387 } 1388 } else { 1389 if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) { 1390 Facebook.disable(); 1391 consent.facebook = false; 1392 } 1393 1394 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 ) ) { 1395 Bing.disable(); 1396 consent.bing = false; 1397 } 1398 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)) { 1399 Analytics.disable(); 1400 consent.ga = false; 1401 consent.gtm = false; 1402 } 1403 1404 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 1405 Pinterest.disable(); 1406 consent.pinterest = false; 1407 } 1408 1409 if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) && ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || !CS_Data.cs_reddit_ldu_mode ) ) { 1410 Reddit.disable(); 1411 consent.reddit = false; 1412 } 1413 } 1414 if (Cookies.get('cs_enabled_advanced_matching') == 'yes') { 1415 Facebook.loadPixel(); 1416 } 1417 } 1418 } 1419 Utils.setupGDPRData( consent ); 1420 } 1421 1422 if (!cs_refresh_after_consent) { 1423 consent_actions(); 1424 1425 $(document).on('click','.cs_action_btn',function(e) { 1426 e.preventDefault(); 1427 1428 let consent = { 1429 facebook: true, 1430 ga: true, 1431 bing: true, 1432 pinterest: true, 1433 gtm: true, 1434 reddit: true, 1435 }; 1436 1437 let elm = $(this), 1438 button_action = elm.attr('data-cs_action'); 1439 1440 if(button_action === 'allow_all') { 1441 Facebook.loadPixel(); 1442 Bing.loadPixel(); 1443 Analytics.loadPixel(); 1444 Pinterest.loadPixel(); 1445 Reddit.loadPixel(); 1446 1447 consent.facebook = true; 1448 consent.bing = true; 1449 consent.ga = true; 1450 consent.pinterest = true; 1451 consent.reddit = true; 1452 consent.gtm = true; 1453 1454 Utils.setupGDPRData( consent ); 1455 } else if ( button_action === 'disable_all' ) { 1456 if ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) { 1457 Facebook.disable(); 1458 consent.facebook = false;
1459 } 1460 1461 if ( typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) { 1462 Bing.disable(); 1463 consent.bing = false; 1464 } 1465 1466 if ( CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined" ) { 1467 Analytics.disable(); 1468 consent.ga = false; 1469 consent.gtm = false; 1470 } 1471 1472 if ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || CS_Data.cs_reddit_ldu_mode == 0 ) { 1473 Reddit.disable(); 1474 consent.reddit = false; 1475 } 1476 1477 Pinterest.disable(); 1478 consent.pinterest = false; 1479 Utils.setupGDPRData( consent ); 1480 } else if ( button_action === 'cs_confirm' ) { 1481 consent_actions(); 1482 } 1483 }); 1484 } 1485 } 1486 /** 1487 * Real Cookie Banner 1488 */ 1489 if(options.gdpr.real_cookie_banner_integration_enabled) { 1490 let consentApi = window.consentApi; 1491 if (consentApi) { 1492 consentApi.consent("http", "_ga", "*") 1493 .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics)); 1494 consentApi.consent("http", "_fbp", "*") 1495 .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook)); 1496 consentApi.consent("http", "_pinterest_sess", ".pinterest.com") 1497 .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest)); 1498 consentApi.consent("http", "_uetsid", "*") 1499 .then(Bing.loadPixel.bind(Bing), Bing.disable.bind(Bing)); 1500 1501 let consent = { 1502 facebook: true, 1503 ga: true, 1504 bing: true, 1505 pinterest: true, 1506 gtm: true, 1507 }; 1508 1509 if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) { 1510 consent.ga = false; 1511 consent.gtm = false; 1512 } 1513 if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) { 1514 consent.facebook = false; 1515 } 1516 if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) { 1517 consent.pinterest = false; 1518 } 1519 if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) { 1520 consent.bing = false; 1521 } 1522 Utils.setupGDPRData( consent ); 1523 } 1524 } 1525 /** 1526 * Cookiebot 1527 */ 1528 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1529 1530 window.addEventListener("CookiebotOnConsentReady", function() { 1531 1532 let consent = { 1533 facebook: true, 1534 ga: true, 1535 bing: true, 1536 pinterest: true, 1537 gtm: true, 1538 }; 1539 1540 Utils.manageCookies(); 1541 if (Cookiebot.consent.marketing) { 1542 Facebook.loadPixel(); 1543 Bing.loadPixel(); 1544 Pinterest.loadPixel(); 1545 1546 consent.facebook = true; 1547 consent.bing = true; 1548 consent.pinterest = true; 1549 } 1550 if (Cookiebot.consent.statistics) { 1551 Analytics.loadPixel(); 1552 1553 consent.ga = true; 1554 consent.gtm = true; 1555 } 1556 if (!Cookiebot.consent.marketing) { 1557 Facebook.disable(); 1558 Pinterest.disable(); 1559 Bing.disable(); 1560 1561 consent.facebook = false;
1562 consent.bing = false; 1563 consent.pinterest = false; 1564 } 1565 if (!Cookiebot.consent.statistics) { 1566 Analytics.disable(); 1567 1568 consent.ga = false; 1569 consent.gtm = false; 1570 } 1571 1572 Utils.setupGDPRData( consent ); 1573 }); 1574 1575 } 1576 1577 /** 1578 * Cookie Notice 1579 */ 1580 if (options.gdpr.cookie_notice_integration_enabled) { 1581 1582 $(document).onFirst('click', '.cn-set-cookie', function () { 1583 1584 let consent = {}; 1585 1586 if ($(this).data('cookie-set') === 'accept') { 1587 Facebook.loadPixel(); 1588 Analytics.loadPixel(); 1589 Pinterest.loadPixel(); 1590 Bing.loadPixel(); 1591 1592 consent = { 1593 facebook: true, 1594 ga: true, 1595 bing: true, 1596 pinterest: true, 1597 gtm: true, 1598 }; 1599 } else { 1600 Facebook.disable(); 1601 Analytics.disable(); 1602 Pinterest.disable(); 1603 Bing.disable(); 1604 1605 consent = { 1606 facebook: false, 1607 ga: false, 1608 bing: false, 1609 pinterest: false, 1610 gtm: false, 1611 }; 1612 } 1613 1614 Utils.setupGDPRData( consent ); 1615 }); 1616 1617 $(document).onFirst('click', '.cn-revoke-cookie', function () { 1618 Facebook.disable(); 1619 Analytics.disable(); 1620 Pinterest.disable(); 1621 Bing.disable(); 1622 1623 let consent = { 1624 facebook: false, 1625 ga: false, 1626 bing: false, 1627 pinterest: false, 1628 gtm: false, 1629 }; 1630 Utils.setupGDPRData( consent ); 1631 1632 }); 1633 1634 } 1635 1636 /** 1637 * Cookie Law Info 1638 */ 1639 if (options.gdpr.cookie_law_info_integration_enabled) { 1640 1641 $(document).onFirst('click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () { 1642 setTimeout(function (){ 1643 let cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy'); 1644 if (typeof cli_cookie !== 'undefined') { 1645 if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) { 1646 if (getCookieYes('analytics') === 'yes') { 1647 Utils.manageCookies(); 1648 } 1649 } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') { 1650 Utils.manageCookies(); 1651 } 1652 } 1653 },1000) 1654 Facebook.loadPixel(); 1655 Analytics.loadPixel(); 1656 Pinterest.loadPixel(); 1657 Bing.loadPixel(); 1658 1659 let consent = { 1660 facebook: true, 1661 ga: true, 1662 bing: true, 1663 pinterest: true, 1664 gtm: true, 1665 }; 1666 Utils.setupGDPRData( consent ); 1667 }); 1668 1669 $(document).onFirst('click', '#cookie_action_close_header_reject, .cky-btn-reject', function () { 1670 Facebook.disable(); 1671 Analytics.disable(); 1672 Pinterest.disable(); 1673 Bing.disable(); 1674 1675 let consent = {
1676 facebook: false, 1677 ga: false, 1678 bing: false, 1679 pinterest: false, 1680 gtm: false, 1681 }; 1682 Utils.setupGDPRData( consent ); 1683 }); 1684 1685 } 1686 1687 }, 1688 1689 setupGDPRData: function ( consent ) { 1690 consent = window.btoa( JSON.stringify( consent ) ); 1691 Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } ); 1692 }, 1693 1694 /** 1695 * DOWNLOAD DOCS 1696 */ 1697 1698 getLinkExtension: function (link) { 1699 1700 // Remove anchor, query string and everything before last slash 1701 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1702 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1703 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1704 1705 // If there's a period left in the URL, then there's a extension 1706 if (link.length > 0 && link.indexOf('.') !== -1) { 1707 link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period 1708 return link; 1709 } else { 1710 return ""; 1711 } 1712 }, 1713 1714 getLinkFilename: function (link) { 1715 1716 // Remove anchor, query string and everything before last slash 1717 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1718 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1719 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1720 1721 // If there's a period left in the URL, then there's a extension 1722 if (link.length > 0 && link.indexOf('.') !== -1) { 1723 return link; 1724 } else { 1725 return ""; 1726 } 1727 }, 1728 /** 1729 * Enrich 1730 */ 1731 isCheckoutPage: function () { 1732 return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') || 1733 $('body').hasClass('edd-checkout'); 1734 }, 1735 addCheckoutFields : function() { 1736 var utm = ""; 1737 var utms = getUTMs() 1738 1739 $.each(utmTerms, function (index, name) { 1740 if(index > 0) { 1741 utm+="|"; 1742 } 1743 utm+=name+":"+utms[name]; 1744 }); 1745 var utmIdList = ""; 1746 var utmsIds = getUTMId() 1747 $.each(utmId, function (index, name) { 1748 if(index > 0) { 1749 utmIdList+="|"; 1750 } 1751 utmIdList+=name+":"+utmsIds[name]; 1752 }); 1753 var utmIdListLast = ""; 1754 var utmsIdsLast = getUTMId(true) 1755 $.each(utmId, function (index, name) { 1756 if(index > 0) { 1757 utmIdListLast+="|"; 1758 } 1759 utmIdListLast+=name+":"+utmsIdsLast[name]; 1760 }); 1761 1762 1763 var utmLast = ""; 1764 var utmsLast = getUTMs(true) 1765 $.each(utmTerms, function (index, name) { 1766 if(index > 0) { 1767 utmLast+="|"; 1768 } 1769 utmLast+=name+":"+utmsLast[name]; 1770 }); 1771 1772 var dateTime = getDateTime(); 1773 var landing = getLandingPageValue(); 1774 var lastLanding = getLandingPageValue(); 1775 var trafic = getTrafficSourceValue(); 1776 var lastTrafic = getTrafficSourceValue(); 1777 1778 var $form = null; 1779 if($('body').hasClass('woocommerce-checkout')) { 1780 $form = $("form.woocommerce-checkout"); 1781 } else { 1782 $form = $("#edd_purchase_form"); 1783 } 1784 var inputs = {'pys_utm':utm, 1785 'pys_utm_id':utmIdList, 1786 'pys_browser_time':dateTime.join("|"), 1787 'pys_landing':landing, 1788 'pys_source':trafic, 1789 'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal", 1790 1791 'last_pys_landing':lastLanding, 1792 'last_pys_source':lastTrafic, 1793 'last_pys_utm':utmLast, 1794 'last_pys_utm_id':utmIdListLast, 1795 } 1796
1797 Object.keys(inputs).forEach(function(key,index) { 1798 $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> "); 1799 }); 1800 1801 1802 }, 1803 getAdvancedFormData: function () { 1804 let dataStr = Cookies.get("pys_advanced_form_data"); 1805 if(dataStr === undefined) { 1806 return {'first_name':"",'last_name':"",'email':"",'phone':""}; 1807 } else { 1808 return JSON.parse(dataStr); 1809 } 1810 } 1811 }; 1812 1813 }(options); 1814 1815 var Facebook = function (options) { 1816 1817 1818 var defaultEventTypes = [ 1819 'PageView', 1820 'ViewContent', 1821 'Search', 1822 'AddToCart', 1823 'AddToWishlist', 1824 'InitiateCheckout', 1825 'AddPaymentInfo', 1826 'Purchase', 1827 'Lead', 1828 1829 'Subscribe', 1830 'CustomizeProduct', 1831 'FindLocation', 1832 'StartTrial', 1833 'SubmitApplication', 1834 'Schedule', 1835 'Contact', 1836 'Donate' 1837 ]; 1838 1839 var initialized = false; 1840 var genereateFbp = function (){ 1841 return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp'); 1842 }; 1843 var genereateFbc = function (){ 1844 return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : '' 1845 }; 1846 // fire server side event gdpr plugin installed 1847 var isApiDisabled = options.gdpr.all_disabled_by_api || 1848 options.gdpr.facebook_disabled_by_api || 1849 options.gdpr.cookiebot_integration_enabled || 1850 options.gdpr.consent_magic_integration_enabled || 1851 options.gdpr.cookie_notice_integration_enabled || 1852 options.gdpr.cookie_law_info_integration_enabled; 1853 1854 /** 1855 * 1856 * @param allData 1857 * @param params 1858 * @returns {string | null} 1859 */ 1860 function sendFbServerEvent(allData,name,params) { 1861 let eventId = null; 1862 if(options.facebook.serverApiEnabled) { 1863 1864 if(allData.e_id === "woo_remove_from_cart") {// server event will sended from hook 1865 Facebook.updateEventId(allData.name); 1866 allData.eventID = Facebook.getEventId(allData.name); 1867 } else { 1868 // send event from server if they was bloc by gdpr or need send with delay 1869 allData.eventID = Utils.generateUniqueId(allData); 1870 1871 if(Cookies.get('_fbp')){ 1872 params._fbp = Cookies.get('_fbp'); 1873 } 1874 if(Cookies.get('_fbc')){ 1875 params._fbc = Cookies.get('_fbc'); 1876 } 1877 1878 if( options.ajaxForServerEvent || isApiDisabled ){ 1879 var json = { 1880 action: 'pys_api_event', 1881 pixel: 'facebook', 1882 event: name, 1883 data:params, 1884 ids:options.facebook.pixelIds, 1885 eventID:allData.eventID, 1886 url:window.location.href, 1887 ajax_event:options.ajax_event 1888 }; 1889 if(allData.hasOwnProperty('woo_order')) { 1890 json['woo_order'] = allData.woo_order; 1891 } 1892 if(allData.hasOwnProperty('edd_order')) { 1893 json['edd_order'] = allData.edd_order; 1894 } 1895 1896 if (allData.e_id === "automatic_event_internal_link" || allData.e_id === "automatic_event_outbound_link") { 1897 setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), 500); 1898 } else if (allData.type != 'static') { 1899 Utils.sendServerAjaxRequest(options.ajaxUrl, json); 1900 } 1901 1902 if ( ( allData.type == 'static' && options.ajaxForServerStaticEvent ) || ( allData.hasOwnProperty( 'ajaxFire' ) && allData.ajaxFire ) ) { 1903 Utils.sendServerAjaxRequest( options.ajaxUrl, json ); 1904 } 1905 } 1906 } 1907 delete params._fbp; 1908 delete params._fbc; 1909 eventId = allData.eventID 1910 } 1911 return eventId; 1912 } 1913 1914 function fireEvent(name, allData) { 1915 1916 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) { 1917 return; 1918 } 1919 1920 var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom'; 1921 var data = allData.params; 1922 var params = {}; 1923 var arg = {}; 1924 Utils.copyProperties(data, params); 1925 let eventId = sendFbServerEvent(allData,name,params) 1926 1927 1928 if("hCR" === name) { 1929 return; 1930 } 1931 1932 if (options.debug) { 1933 console.log('[Facebook] ' + name, params,"eventID",eventId); 1934 } 1935 1936 if(eventId != null) { 1937 arg.eventID = eventId; 1938 } 1939 1940 fbq(actionType, name, params, arg); 1941 1942 } 1943 1944 /** 1945 * Public API 1946 */ 1947 return { 1948 tag: function() { 1949 return "facebook"; 1950 }, 1951 isEnabled: function () { 1952 return options.hasOwnProperty('facebook'); 1953 }, 1954 1955 disable: function () { 1956 initialized = false;
1957 }, 1958 advancedMatching: function () { 1959 if(options.facebook.advancedMatchingEnabled) { 1960 let advancedMatchingForm = Utils.getAdvancedFormData(); 1961 let advancedMatching = {}; 1962 if(Object.keys(options.facebook.advancedMatching).length > 0) { 1963 advancedMatching = options.facebook.advancedMatching; 1964 } 1965 1966 if(!advancedMatching.hasOwnProperty("em") 1967 && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) { 1968 advancedMatching["em"] = advancedMatchingForm["email"]; 1969 } 1970 if(!advancedMatching.hasOwnProperty("ph") 1971 && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) { 1972 advancedMatching["ph"] = advancedMatchingForm["phone"]; 1973 } 1974 if(!advancedMatching.hasOwnProperty("fn") 1975 && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) { 1976 advancedMatching["fn"] = advancedMatchingForm["first_name"]; 1977 } 1978 if(!advancedMatching.hasOwnProperty("ln") 1979 && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) { 1980 advancedMatching["ln"] = advancedMatchingForm["last_name"]; 1981 } 1982 if(!advancedMatching.hasOwnProperty("external_id")){ 1983 if (Cookies.get('pbid') || (options.hasOwnProperty('pbid') && options.pbid)) { 1984 advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : options.pbid; 1985 } 1986 } 1987 else if(advancedMatching.external_id != Cookies.get('pbid')) 1988 { 1989 advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id; 1990 } 1991 if(Object.keys(advancedMatching).length > 0) { 1992 return advancedMatching; 1993 } 1994 } 1995 return false 1996 }, 1997 /** 1998 * Load pixel's JS 1999 */ 2000 loadPixel: function () { 2001 2002 if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) { 2003 return; 2004 } 2005 2006 !function (f, b, e, v, n, t, s) { 2007 if (f.fbq) return; 2008 n = f.fbq = function () { 2009 n.callMethod ? 2010 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 2011 }; 2012 if (!f._fbq) f._fbq = n; 2013 n.push = n; 2014 n.loaded = !0; 2015 n.version = '2.0'; 2016 n.agent = 'dvpixelyoursite'; 2017 n.queue = []; 2018 t = b.createElement(e); 2019 t.async = !0; 2020 t.src = v; 2021 s = b.getElementsByTagName(e)[0]; 2022 s.parentNode.insertBefore(t, s) 2023 }(window, 2024 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 2025 2026 let expires = parseInt(options.cookie_duration); 2027 if(!Cookies.get('_fbp')) { 2028 Cookies.set('_fbp',genereateFbp(), { expires: expires,path: '/',domain: domain }); 2029 } 2030 2031 if(getUrlParameter('fbclid')) { 2032 Cookies.set('_fbc',genereateFbc(), { expires: expires,path: '/',domain: domain }); 2033 } 2034 // initialize pixel 2035 options.facebook.pixelIds.forEach(function (pixelId) { 2036 if (options.facebook.removeMetadata) { 2037 fbq('set', 'autoConfig', false, pixelId); 2038 } 2039 let advancedMatching = Facebook.advancedMatching(); 2040 2041 if ( +options.facebook.meta_ldu === 1 ) { 2042 fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 ); 2043 } 2044 2045 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 2046 if(!advancedMatching) { 2047 fbq('init', pixelId); 2048 } else { 2049 var test_prefix = CS_Data.test_prefix; 2050 var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix); 2051 if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) { 2052 if (cs_advanced_matching == 'yes') { 2053 fbq('init', pixelId, advancedMatching); 2054 } else { 2055 fbq('init', pixelId); 2056 } 2057 } else { 2058 fbq('init', pixelId, advancedMatching); 2059 } 2060 } 2061 } else { 2062 if(!advancedMatching) { 2063 fbq('init', pixelId); 2064 } else { 2065 fbq('init', pixelId, advancedMatching); 2066 } 2067 } 2068 }); 2069 2070 initialized = true; 2071 2072 Utils.fireStaticEvents('facebook'); 2073 2074 }, 2075 2076 fireEvent: function (name, data) { 2077 2078 if (!initialized || !this.isEnabled()) { 2079 return false;
2080 } 2081 2082 data.delay = data.delay || 0; 2083 data.params = data.params || {}; 2084 2085 if (data.delay === 0) { 2086 2087 fireEvent(name, data); 2088 2089 } else { 2090 2091 setTimeout(function (name, params) { 2092 fireEvent(name, params); 2093 }, data.delay * 1000, name, data); 2094 2095 } 2096 2097 return true; 2098 2099 }, 2100 2101 onCommentEvent: function (event) { 2102 this.fireEvent(event.name, event); 2103 }, 2104 2105 onDownloadEvent: function (event) { 2106 this.fireEvent(event.name, event); 2107 }, 2108 2109 onFormEvent: function (event) { 2110 2111 this.fireEvent(event.name, event); 2112 2113 }, 2114 2115 onWooAddToCartOnButtonEvent: function (product_id) { 2116 2117 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2118 return; 2119 var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]; 2120 window.pysWooProductData = window.pysWooProductData || []; 2121 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2122 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 2123 event = Utils.copyProperties(event, {}) 2124 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params) 2125 this.fireEvent(event.name, event); 2126 } 2127 } 2128 }, 2129 2130 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 2131 2132 window.pysWooProductData = window.pysWooProductData || []; 2133 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2134 return; 2135 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2136 2137 if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) { 2138 product_id = parseInt($form.find('input[name="variation_id"]').val()); 2139 } 2140 2141 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2142 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 2143 2144 2145 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params); 2146 2147 var groupValue = 0; 2148 if(product_type === Utils.PRODUCT_GROUPED ) { 2149 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 2150 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 2151 var quantity = parseInt($(this).val()); 2152 if(isNaN(quantity)) { 2153 quantity = 0; 2154 } 2155 var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId]; 2156 2157 if(quantity == 0) { 2158 event.params.content_ids.forEach(function(el,index,array) { 2159 if(el == childItem.content_id) { 2160 array.splice(index, 1); 2161 } 2162 }); 2163 } 2164 2165 if(event.params.hasOwnProperty('contents')) { 2166 event.params.contents.forEach(function(el,index,array) { 2167 if(el.id == childItem.content_id) { 2168 if(quantity > 0){ 2169 el.quantity = quantity; 2170 } else { 2171 array.splice(index, 1); 2172 } 2173 } 2174 }); 2175 } 2176 2177 2178 groupValue += childItem.price * quantity; 2179 }); 2180 if(groupValue == 0) return;
2180 // skip if no items selected 2181 } 2182 2183 // maybe customize value option 2184 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 2185 2186 if(product_type === Utils.PRODUCT_GROUPED) { 2187 event.params.value = groupValue; 2188 } else if(product_type === Utils.PRODUCT_BUNDLE) { 2189 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 2190 var items_sum = getBundlePriceOnSingleProduct(data); 2191 event.params.value = (parseInt(data.base_price) + items_sum )* qty; 2192 } else { 2193 event.params.value = event.params.value * qty; 2194 } 2195 } 2196 2197 // only when non Facebook for WooCommerce logic used 2198 if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) { 2199 event.params.contents[0].quantity = qty; 2200 } 2201 2202 this.fireEvent(event.name, event); 2203 2204 } 2205 } 2206 }, 2207 2208 onWooRemoveFromCartEvent: function (event) { 2209 this.fireEvent(event.name, event); 2210 }, 2211 2212 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 2213 2214 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2215 return; 2216 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 2217 2218 if (window.pysEddProductData.hasOwnProperty(download_id)) { 2219 2220 var index; 2221 2222 if (price_index) { 2223 index = download_id + '_' + price_index; 2224 } else { 2225 index = download_id; 2226 } 2227 2228 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 2229 if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) { 2230 2231 2232 Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params) 2233 2234 // maybe customize value option 2235 if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') { 2236 event.params.value = event.params.value * qty; 2237 } 2238 2239 // update contents qty param 2240 var contents = event.params.contents; 2241 contents[0].quantity = qty; 2242 event.params.contents = contents; 2243 2244 this.fireEvent(event.name,event); 2245 2246 } 2247 } 2248 2249 } 2250 2251 }, 2252 2253 onEddRemoveFromCartEvent: function (event) { 2254 this.fireEvent(event.name, event); 2255 }, 2256 onPageScroll: function (event) { 2257 this.fireEvent(event.name, event); 2258 }, 2259 onTime: function (event) { 2260 this.fireEvent(event.name, event); 2261 }, 2262 initEventIdCookies: function (key) { 2263 var ids = {}; 2264 ids[key] = pys_generate_token(36) 2265 Cookies.set('pys_fb_event_id', JSON.stringify(ids)); 2266 }, 2267 updateEventId:function(key) { 2268 var cooData = Cookies.get("pys_fb_event_id") 2269 if(cooData === undefined) { 2270 this.initEventIdCookies(key); 2271 } else { 2272 var data = JSON.parse(cooData); 2273 data[key] = pys_generate_token(36); 2274 Cookies.set('pys_fb_event_id', JSON.stringify(data) ); 2275 } 2276 }, 2277 2278 getEventId:function (key) { 2279 var data = Cookies.get("pys_fb_event_id"); 2280 if(data === undefined) {
2281 this.initEventIdCookies(key); 2282 data = Cookies.get("pys_fb_event_id"); 2283 } 2284 return JSON.parse(data)[key]; 2285 }, 2286 2287 sendFacebookRestAPIRequest: function(allData, name, params) { 2288 if (typeof window.pysFacebookRest === 'undefined' || !window.pysFacebookRest.restApiUrl) { 2289 return; 2290 } 2291 2292 const restApiData = { 2293 event: name, 2294 data: JSON.stringify(params), 2295 ids: allData.pixelIds || options.facebook.pixelIds, 2296 eventID: allData.eventID, 2297 woo_order: allData.woo_order || 0, 2298 edd_order: allData.edd_order || 0 2299 }; 2300 2301 // Try sendBeacon first 2302 if (navigator.sendBeacon) { 2303 const formData = new FormData(); 2304 Object.keys(restApiData).forEach(key => { 2305 if (Array.isArray(restApiData[key])) { 2306 restApiData[key].forEach(value => { 2307 formData.append(key + '[]', value); 2308 }); 2309 } else { 2310 formData.append(key, restApiData[key]); 2311 } 2312 }); 2313 2314 if (navigator.sendBeacon(window.pysFacebookRest.restApiUrl, formData)) { 2315 return; 2316 } 2317 } 2318 2319 // Fallback to fetch 2320 fetch(window.pysFacebookRest.restApiUrl, { 2321 method: 'POST', 2322 headers: { 2323 'Content-Type': 'application/x-www-form-urlencoded', 2324 }, 2325 body: new URLSearchParams(restApiData) 2326 }).catch(() => { 2327 // Fallback to AJAX if fetch fails 2328 this.sendAjaxFallback(allData, name, params); 2329 }); 2330 }, 2331 2332 sendAjaxFallback: function(allData, name, params) { 2333 var json = { 2334 action: 'pys_api_event', 2335 pixel: 'facebook', 2336 event: name, 2337 data: params, 2338 ids: allData.pixelIds || options.facebook.pixelIds, 2339 eventID: allData.eventID, 2340 url: window.location.href, 2341 ajax_event: options.ajax_event 2342 }; 2343 if (allData.hasOwnProperty('woo_order')) { 2344 json['woo_order'] = allData.woo_order; 2345 } 2346 if (allData.hasOwnProperty('edd_order')) { 2347 json['edd_order'] = allData.edd_order; 2348 } 2349 2350 Utils.sendServerAjaxRequest(options.ajaxUrl, json); 2351 }, 2352 }; 2353 2354 }(options); 2355 2356 var Analytics = function (options) { 2357 2358 var initialized = false; 2359 2360 /** 2361 * Fires event 2362 * 2363 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 2364 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 2365 * @link: https://developers.google.com/gtagjs/reference/event 2366 * @link: https://developers.google.com/gtagjs/reference/parameter 2367 * 2368 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 2369 * 2370 * @param name 2371 * @param data 2372 */ 2373 function fireEvent(name, data) { 2374 2375 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) { 2376 return; 2377 } 2378 2379 var eventParams = Utils.copyProperties(data, {}); 2380 var _fireEvent = function (tracking_id,name,params) { 2381 2382 params['send_to'] = tracking_id; 2383 2384 if (options.debug) { 2385 console.log('[Google Analytics #' + tracking_id + '] ' + name, params); 2386 } 2387 2388 gtag('event', name, params); 2389 2390 }; 2391 options.ga.trackingIds.forEach(function (tracking_id) { 2392 var copyParams = Utils.copyProperties(eventParam
2392s, {}); // copy params because mapParamsTov4 can modify it 2393 var params = mapParamsTov4(tracking_id,name,copyParams) 2394 _fireEvent(tracking_id,name,params); 2395 }); 2396 2397 } 2398 function mapParamsTov4(tag,name,param) { 2399 //GA4 automatically collects a number of parameters for all events 2400 delete param.landing_page; 2401 // end 2402 if(isv4(tag)) { 2403 delete param.traffic_source; 2404 delete param.event_category; 2405 delete param.event_label; 2406 delete param.ecomm_prodid; 2407 delete param.ecomm_pagetype; 2408 delete param.ecomm_totalvalue; 2409 if(name === 'search') { 2410 param['search'] = param.search_term; 2411 delete param.search_term; 2412 delete param.dynx_itemid; 2413 delete param.dynx_pagetype; 2414 delete param.dynx_totalvalue; 2415 } 2416 } 2417 return param; 2418 } 2419 2420 function isv4(tag) { 2421 return tag.indexOf('G') === 0; 2422 } 2423 2424 /** 2425 * Public API 2426 */ 2427 return { 2428 tag: function() { 2429 return "ga"; 2430 }, 2431 isEnabled: function () { 2432 return options.hasOwnProperty('ga'); 2433 }, 2434 2435 disable: function () { 2436 initialized = false; 2437 }, 2438 2439 loadPixel: function () { 2440 2441 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 2442 return; 2443 } 2444 2445 Utils.loadGoogleTag(options.ga.trackingIds[0]); 2446 var config = {}; 2447 // Cross-Domain tracking 2448 if (options.ga.crossDomainEnabled) { 2449 config.linker = { 2450 accept_incoming: options.ga.crossDomainAcceptIncoming, 2451 domains: options.ga.crossDomainDomains 2452 }; 2453 } 2454 var ids = options.ga.trackingIds; 2455 // configure tracking ids 2456 ids.forEach(function (trackingId,index) { 2457 var obj = options.ga.isDebugEnabled; 2458 var searchValue = "index_"+index; 2459 var config_for_tag = Object.assign({}, options.config); 2460 config_for_tag.debug_mode = false;
2461 config_for_tag.send_page_view = !options.ga.custom_page_view_event; 2462 for (var key in obj) { 2463 if (obj.hasOwnProperty(key) && obj[key] === searchValue) { 2464 config_for_tag.debug_mode = true; 2465 break; 2466 } 2467 } 2468 if(!config_for_tag.debug_mode) 2469 { 2470 delete config_for_tag.debug_mode; 2471 } 2472 if(isv4(trackingId)) { 2473 if(options.ga.disableAdvertisingFeatures) { 2474 config_for_tag.allow_google_signals = false 2475 } 2476 if(options.ga.disableAdvertisingPersonalization) { 2477 config_for_tag.allow_ad_personalization_signals = false 2478 } 2479 } 2480 if(options.ga.hasOwnProperty('additionalConfig')){ 2481 if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){ 2482 config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection; 2483 } 2484 2485 } 2486 if(options.ga.hasOwnProperty('serverContainerUrls')){ 2487 if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){ 2488 if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){ 2489 config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url; 2490 } 2491 if(options.ga.serverContainerUrls[trackingId].transport_url != ''){ 2492 config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url; 2493 } 2494 } 2495 } 2496 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 2497 2498 var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category']; 2499 if (options.gdpr['analytics_prior_consent_enabled']) { 2500 if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) { 2501 gtag('config', trackingId, config_for_tag); 2502 } 2503 } else { 2504 if (Cookiebot.consent[cookiebot_consent_category]) { 2505 gtag('config', trackingId, config_for_tag); 2506 } 2507 } 2508 } 2509 else 2510 { 2511 gtag('config', trackingId, config_for_tag); 2512 } 2513 }); 2514 2515 initialized = true; 2516 2517 Utils.fireStaticEvents('ga'); 2518 2519 }, 2520 2521 fireEvent: function (name, data) { 2522 2523 if (!initialized || !this.isEnabled()) { 2524 return false; 2525 } 2526 2527 data.delay = data.delay || 0; 2528 data.params = data.params || {}; 2529 data.params.eventID = Utils.generateUniqueId(data); 2530 if (data.delay === 0) { 2531 2532 fireEvent(name, data.params); 2533 2534 } else { 2535 2536 setTimeout(function (name, params) { 2537 fireEvent(name, params); 2538 }, data.delay * 1000, name, data.params); 2539 2540 } 2541 2542 return true; 2543 2544 }, 2545 2546 onCommentEvent: function (event) { 2547 this.fireEvent(event.name, event); 2548 }, 2549 2550 onDownloadEvent: function (event) { 2551 this.fireEvent(event.name, event); 2552 }, 2553 2554 onFormEvent: function (event) { 2555 this.fireEvent(event.name, event); 2556 }, 2557 2558 onWooAddToCartOnButtonEvent: function (product_id) { 2559 2560 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2561 return; 2562 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2563 2564 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2565 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 2566 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params) 2567 this.fireEvent(event.name, event); 2568 } 2569 } 2570 2571 2572 }, 2573 2574 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 2575 2576 window.pysWooProductData = window.pysWooProductData || []; 2577 2578 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2579 return; 2580 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2581 2582 if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) { 2583 product_id = parseInt($form.find('input[name="variation_id"]').val()); 2584 } 2585 2586 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2587 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 2588 2589 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params); 2590 if(product_type === Utils.PRODUCT_GROUPED ) { 2591 var groupValue = 0; 2592 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 2593 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 2594 var quantity = parseInt($(this).val()); 2595 if(isNaN(quantity)) { 2596 quantity = 0; 2597 } 2598 var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId]; 2599 // update quantity
2600 event.params.items.forEach(function(el,index,array) { 2601 if(el.id == childItem.content_id) { 2602 if(quantity > 0){ 2603 el.quantity = quantity; 2604 } else { 2605 array.splice(index, 1); 2606 } 2607 } 2608 }); 2609 groupValue += childItem.price * quantity; 2610 }); 2611 if(options.woo.addToCartOnButtonValueEnabled && 2612 options.woo.addToCartOnButtonValueOption !== 'global' && 2613 event.params.hasOwnProperty('ecomm_totalvalue')) { 2614 event.params.ecomm_totalvalue = groupValue; 2615 } 2616 2617 if(groupValue == 0) return; // skip if no items selected 2618 } else { 2619 // update items qty param 2620 event.params.items[0].quantity = qty; 2621 } 2622 2623 // maybe customize value option 2624 if (options.woo.addToCartOnButtonValueEnabled && 2625 options.woo.addToCartOnButtonValueOption !== 'global' && 2626 product_type !== Utils.PRODUCT_GROUPED) 2627 { 2628 if(event.params.hasOwnProperty('ecomm_totalvalue')) { 2629 event.params.ecomm_totalvalue = event.params.items[0].price * qty; 2630 } 2631 2632 } 2633 2634 2635 this.fireEvent(event.name, event); 2636 } 2637 } 2638 2639 }, 2640 2641 onWooRemoveFromCartEvent: function (event) { 2642 2643 this.fireEvent(event.name, event); 2644 2645 }, 2646 2647 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 2648 2649 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2650 return; 2651 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 2652 2653 2654 if (window.pysEddProductData.hasOwnProperty(download_id)) { 2655 2656 var index; 2657 2658 if (price_index) { 2659 index = download_id + '_' + price_index; 2660 } else { 2661 index = download_id; 2662 } 2663 2664 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 2665 if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) { 2666 2667 Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params); 2668 2669 // update items qty param 2670 event.params.items[0].quantity = qty; 2671 2672 this.fireEvent(event.name,event); 2673 2674 } 2675 } 2676 2677 } 2678 2679 }, 2680 2681 onEddRemoveFromCartEvent: function (event) { 2682 this.fireEvent(event.name, event); 2683 }, 2684 onPageScroll: function (event) { 2685 this.fireEvent(event.name, event); 2686 }, 2687 onTime: function (event) { 2688 this.fireEvent(event.name, event); 2689 }, 2690 2691 }; 2692 2693 }(options); 2694 2695 var GTM = function (options) { 2696 var initialized = false; 2697 2698 var datalayer_name = 'dataLayer'; 2699 /* 2700 * @param name 2701 * @param data 2702 */ 2703 function fireEvent(name, event) { 2704 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) { 2705 return; 2706 } 2707 2708 2709 var eventParams = event.params; 2710 var data = event.params; 2711 var valuesArray = Object.values(event.trackingIds); 2712 var ids = valuesArray;
2713 Utils.copyProperties(Utils.getRequestParams(), eventParams); 2714 var _fireEvent = function (tracking_id,name,params, event=null) { 2715 var eventData = {}; 2716 var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0; 2717 if(ContainerCodeHasTag) { 2718 params['send_to'] = tracking_id; 2719 } 2720 else if(!options.gtm.gtm_just_data_layer){ 2721 return 2722 } 2723 2724 if (params.hasOwnProperty('ecommerce')) { 2725 eventData.ecommerce = params.ecommerce; 2726 delete params.ecommerce; 2727 } 2728 2729 var automatedParams = { ...params }; 2730 [params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]); 2731 if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) { 2732 eventData.automatedParameters = automatedParams; 2733 } 2734 2735// Move custom parameters to eventData 2736 2737 if (params.hasOwnProperty(params['manualName'])) { 2738 eventData[params['manualName']] = params[params['manualName']]; 2739 delete params[params['manualName']]; 2740 } 2741 2742 ['manualName','triggerType'].forEach(key => { 2743 if (params.hasOwnProperty(key)) { 2744 eventData[key] = params[key]; 2745 delete params[key]; 2746 } 2747 }); 2748 2749 eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 2750 2751 eventData.event = name; 2752 2753 if (options.debug) { 2754 if (ContainerCodeHasTag){ 2755 console.log('[Google GTM #' + tracking_id + '] ' + name, eventData); 2756 } 2757 else { 2758 console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData); 2759 } 2760 } 2761 window[datalayer_name].push(eventData); 2762 2763 }; 2764 2765 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it 2766 2767 var params = mapParamsToGTM(ids,name,copyParams) 2768 2769 params.event_id = Utils.generateUniqueId(event); 2770 2771 _fireEvent(ids, name, params, event); 2772 } 2773 2774 function normalizeEventName(eventName) { 2775 2776 var matches = { 2777 ViewContent: 'view_item', 2778 AddToCart: 'add_to_cart', 2779 AddToWishList: 'add_to_wishlist', 2780 InitiateCheckout: 'begin_checkout', 2781 Purchase: 'purchase', 2782 Lead: 'generate_lead', 2783 CompleteRegistration: 'sign_up', 2784 AddPaymentInfo: 'set_checkout_option' 2785 }; 2786 2787 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 2788 2789 } 2790 2791 function mapParamsToGTM(tag,name,param) { 2792 //GA4 automatically collects a number of parameters for all events 2793 var hasGTM = false; 2794 2795 // end 2796 if (Array.isArray(tag)) { 2797 hasGTM = tag.some(function (element) { 2798 return isGTM(element); 2799 }); 2800 } else if(isGTM(tag)) { 2801 // tag is a string and matches GTM 2802 hasGTM = true; 2803 } 2804 if(hasGTM) { 2805 delete param.event_category; 2806 delete param.event_label; 2807 2808 delete param.analytics_storage; 2809 delete param.ad_storage; 2810 delete param.ad_user_data; 2811 delete param.ad_personalization; 2812 2813 if(name === 'search') { 2814 param['search'] = param.search_term; 2815 delete param.search_term; 2816 delete param.dynx_itemid; 2817 delete param.dynx_pagetype; 2818 delete param.dynx_totalvalue; 2819 } 2820 } 2821 return param; 2822 } 2823 2824 function isGTM(tag) { 2825 return tag.indexOf('GTM') === 0; 2826 } 2827 /** 2828 * Public API 2829 */ 2830 return { 2831 tag: function() { 2832 return "gtm"; 2833 }, 2834 isEnabled: function () { 2835 return options.hasOwnProperty('gtm'); 2836 }, 2837 disable: function () { 2838 initialized = false;
2839 }, 2840 updateEnhancedConversionData : function () { 2841 if (!initialized || !this.isEnabled()) { 2842 return; 2843 } 2844 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) { 2845 var advanced = Utils.getAdvancedFormData(); 2846 if (Object.keys(advanced).length > 0) { 2847 window[datalayer_name].push({'user_data' : advanced}); 2848 } 2849 } 2850 }, 2851 loadPixel: function () { 2852 2853 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 2854 return; 2855 } 2856 datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 2857 2858 for (var i = 0; i < options.gtm.trackingIds.length; i++) { 2859 var trackingId = options.gtm.trackingIds[i]; 2860 if (!options.gtm.gtm_just_data_layer) { 2861 console.log('[PYS] Google Tag Manager container code loaded'); 2862 Utils.loadGTMScript(trackingId); 2863 break; 2864 } 2865 } 2866 if(options.gtm.gtm_just_data_layer) { 2867 console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!"); 2868 console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!"); 2869 if(options.gtm.trackingIds.length == 0){ 2870 Utils.loadGTMScript(); 2871 } 2872 } 2873 2874 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){ 2875 var advanced = Utils.getAdvancedFormData(); 2876 if(Object.keys(advanced).length > 0){ 2877 window[datalayer_name].push({'user_data' : advanced}); 2878 } 2879 } 2880 2881 2882 var config = {}; 2883 2884 if(options.user_id && options.user_id != 0) { 2885 config.user_id = options.user_id; 2886 } 2887 2888 // Cross-Domain tracking 2889 2890 var ids = options.gtm.trackingIds; 2891 2892 2893 initialized = true; 2894 2895 Utils.fireStaticEvents('gtm'); 2896 }, 2897 2898 fireEvent: function (name, data) { 2899 2900 if (!initialized || !this.isEnabled()) { 2901 return false; 2902 } 2903 2904 data.delay = data.delay || 0; 2905 data.params = data.params || {}; 2906 2907 if (data.delay === 0) { 2908 2909 fireEvent(name, data); 2910 2911 } else { 2912 2913 setTimeout(function (name, params) { 2914 fireEvent(name, params); 2915 }, data.delay * 1000, name, data); 2916 2917 } 2918 2919 return true; 2920 2921 }, 2922 2923 onCommentEvent: function (event) { 2924 this.fireEvent(event.name, event); 2925 }, 2926 2927 onDownloadEvent: function (event) { 2928 this.fireEvent(event.name, event); 2929 }, 2930 2931 onFormEvent: function (event) { 2932 this.fireEvent(event.name, event); 2933 }, 2934 2935 onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) { 2936 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2937 return; 2938 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2939 2940 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2941 if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) { 2942 Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params) 2943 this.fireEvent(event.name, event); 2944 } 2945 } 2946 2947 }, 2948 2949 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) { 2950 window.pysWooProductData = window.pysWooProductData || []; 2951 2952 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2953 return; 2954 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2955 2956 if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) { 2957 product_id = parseInt($form.find('input[name="variation_id"]').val()); 2958 } 2959 2960 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2961 if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) { 2962 2963 Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params); 2964 2965 params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params; 2966 2967 if(product_type === Utils.PRODUCT_GROUPED ) { 2968 var groupValue = 0; 2969 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 2970 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 2971 var quantity = parseInt($(this).val()); 2972 if(isNaN(quantity)) { 2973 quantity = 0; 2974 } 2975 var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId];
2976 params.items.forEach(function(el,index,array) { 2977 if(el.id == childItem.content_id) { 2978 if(quantity > 0){ 2979 el.quantity = quantity; 2980 el.price = childItem.price; 2981 } else { 2982 array.splice(index, 1); 2983 } 2984 } 2985 }); 2986 groupValue += childItem.price * quantity; 2987 }); 2988 2989 if(options.woo.addToCartOnButtonValueEnabled && 2990 options.woo.addToCartOnButtonValueOption !== 'global' && 2991 params.hasOwnProperty('value')) { 2992 params.value = groupValue; 2993 } 2994 2995 if(groupValue == 0) return; // skip if no items selected 2996 } else { 2997 // update items qty param 2998 params.items[0].quantity = qty; 2999 } 3000 3001 // maybe customize value option 3002 if (options.woo.addToCartOnButtonValueEnabled && 3003 options.woo.addToCartOnButtonValueOption !== 'global' && 3004 product_type !== Utils.PRODUCT_GROUPED) 3005 { 3006 if(params.hasOwnProperty('value')) { 3007 params.value = params.items[0].price * qty; 3008 } 3009 3010 } 3011 3012 3013 this.fireEvent(event.name, event); 3014 } 3015 } 3016 3017 }, 3018 3019 onWooRemoveFromCartEvent: function (event) { 3020 3021 this.fireEvent(event.name, event); 3022 3023 }, 3024 3025 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 3026 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3027 return; 3028 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 3029 3030 3031 if (window.pysEddProductData.hasOwnProperty(download_id)) { 3032 3033 var index; 3034 3035 if (price_index) { 3036 index = download_id + '_' + price_index; 3037 } else { 3038 index = download_id; 3039 } 3040 3041 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 3042 if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) { 3043 3044 Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params); 3045 item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0]; 3046 // update items qty param 3047 item.quantity = qty; 3048 3049 this.fireEvent(event.name,event); 3050 3051 } 3052 } 3053 3054 } 3055 3056 }, 3057 3058 onEddRemoveFromCartEvent: function (event) { 3059 this.fireEvent(event.name, event); 3060 }, 3061 onPageScroll: function (event) { 3062 this.fireEvent(event.name, event); 3063 }, 3064 onTime: function (event) { 3065 this.fireEvent(event.name, event); 3066 }, 3067 }; 3068 3069 }(options); 3070 3071 var getPixelBySlag = function getPixelBySlag(slug) { 3072 switch (slug) { 3073 case "facebook": return window.pys.Facebook; 3074 case "ga": return window.pys.Analytics; 3075 case "gtm": return window.pys.GTM; 3076 case "bing": return window.pys.Bing; 3077 case "pinterest": return window.pys.Pinterest; 3078 case "reddit": return window.pys.Reddit; 3079 } 3080 } 3081
3082 window.pys = window.pys || {}; 3083 window.pys.Facebook = Facebook; 3084 window.pys.Analytics = Analytics; 3085 window.pys.GTM = GTM; 3086 window.pys.Utils = Utils; 3087 window.pys.getPixelBySlag = getPixelBySlag; 3088 3089 // Export getPixelBySlag globally for backward compatibility 3090 window.getPixelBySlag = getPixelBySlag; 3091 3092 3093 $(document).ready(function () { 3094 3095 if($("#pys_late_event").length > 0) { 3096 var dirAttr = $("#pys_late_event").attr("dir"); 3097 if (dirAttr) { 3098 try { 3099 var events = JSON.parse(dirAttr); 3100 } catch (e) { 3101 console.warn("Invalid JSON in pys_late_event dir attribute:", e); 3102 } 3103 } else { 3104 console.warn("pys_late_event dir attribute is undefined or empty"); 3105 } 3106 if (events) { 3107 for (var key in events) { 3108 var event = {}; 3109 event[events[key].e_id] = [events[key]]; 3110 if (options.staticEvents.hasOwnProperty(key)) { 3111 Object.assign(options.staticEvents[key], event); 3112 } else { 3113 options.staticEvents[key] = event; 3114 } 3115 } 3116 } 3117 } 3118 3119 var Pinterest = Utils.setupPinterestObject(); 3120 var Bing = Utils.setupBingObject(); 3121 var Reddit = Utils.setupRedditObject(); 3122 3123 if(options.hasOwnProperty('cookie')) 3124 { 3125 if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie) 3126 { 3127 Cookies.remove('pbid') 3128 } 3129 if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie) 3130 { 3131 Cookies.remove('pys_advanced_form_data') 3132 } 3133 if(options.cookie.disabled_landing_page_cookie || options.cookie.disabled_all_cookie) 3134 { 3135 Cookies.remove('pys_landing_page') 3136 Cookies.remove('last_pys_landing_page') 3137 } 3138 if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie) 3139 { 3140 Cookies.remove('pysTrafficSource') 3141 Cookies.remove('last_pysTrafficSource') 3142 } 3143 if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie) 3144 { 3145 Cookies.remove('pys_first_visit') 3146 3147 } 3148 if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie) 3149 { 3150 $.each(Utils.utmTerms, function (index, name) { 3151 Cookies.remove('pys_' + name) 3152 }); 3153 $.each(Utils.utmTerms, function (index, name) { 3154 Cookies.remove('last_pys_' + name) 3155 }); 3156 } 3157 if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie) 3158 { 3159 $.each(Utils.utmId,function(index,name) { 3160 Cookies.remove('pys_' + name) 3161 }) 3162 $.each(Utils.utmId,function(index,name) { 3163 Cookies.remove('last_pys_' + name) 3164 }); 3165 } 3166 } 3167 3168 3169 if (options.gdpr.cookie_law_info_integration_enabled) { 3170 var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('viewed_cookie_policy'); 3171 3172 if (typeof cli_cookie !== 'undefined') { 3173 if (cli_cookie === Cookies.get('cookieyes-consent') && getCookieYes('analytics') == 'yes') { 3174 Utils.manageCookies(); 3175 } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') { 3176 Utils.manageCookies(); 3177 } 3178 } 3179 } 3180 3181 if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 3182 if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) { 3183 Utils.manageCookies(); 3184 } else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) { 3185 Utils.manageCookies(); 3186 } 3187 } else { 3188 Utils.manageCookies(); 3189 } 3190 3191 Utils.setupGdprCallbacks(); 3192 // page scroll event 3193 if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll") 3194 ) { 3195 3196 var singlePageScroll = function () { 3197 3198 3199 var docHeight = $(document).height() - $(window).height(); 3200 var isFired = false;
3201 3202 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) { 3203 var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll); 3204 for(var i = 0;i<pixels.length;i++) { 3205 var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]); 3206 var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions 3207 3208 if(scroll < $(window).scrollTop()) { 3209 if ( pixels[i] !== 'reddit') { 3210 Utils.copyProperties( Utils.getRequestParams(), event.params ); 3211 } 3212 getPixelBySlag( pixels[ i ] ).onPageScroll( event ); 3213 isFired = true 3214 } 3215 } 3216 } 3217 if(isFired) { 3218 $(document).off("scroll",singlePageScroll); 3219 } 3220 } 3221 $(document).on("scroll",singlePageScroll); 3222 } 3223 3224 3225 if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) { 3226 var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page); 3227 var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel 3228 setTimeout(function(){ 3229 for(var i = 0;i<pixels.length;i++) { 3230 var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]); 3231 3232 if ( pixels[i] !== 'reddit') {
3233 Utils.copyProperties(Utils.getRequestParams(), event.params); 3234 } 3235 getPixelBySlag(pixels[i]).onTime(event); 3236 } 3237 },time*1000); 3238 } 3239 3240 // setup Click Event 3241 if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) { 3242 3243 $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) { 3244 3245 var $elem = $(this); 3246 3247 // Download 3248 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") 3249 ) { 3250 var isFired = false; 3251 if ($elem.is('a')) { 3252 var href = $elem.attr('href'); 3253 if (typeof href !== "string") { 3254 return; 3255 } 3256 href = href.trim(); 3257 var extension = Utils.getLinkExtension(href); 3258 var track_download = false; 3259 3260 if (extension.length > 0) { 3261 3262 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) { 3263 var pixels = Object.keys(options.dynamicEvents.automatic_event_download); 3264 for (var i = 0; i < pixels.length; i++) { 3265 var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]); 3266 var extensions = event.extensions; 3267 if (extensions.includes(extension)) { 3268 3269 if( pixels[i] == "tiktok" || pixels[i] == "reddit" ) { 3270 getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event); 3271 } else { 3272 if (options.enable_remove_download_url_param) { 3273 href = href.split('?')[0]; 3274 } 3275 event.params.download_url = href; 3276 event.params.download_type = extension; 3277 event.params.download_name = Utils.getLinkFilename(href); 3278 getPixelBySlag(pixels[i]).onDownloadEvent(event); 3279 } 3280 3281 isFired = true; 3282 } 3283 } 3284 } 3285 } 3286 } 3287 if(isFired) { // prevent duplicate events on the same element 3288 return; 3289 } 3290 } 3291 }); 3292 } 3293 3294 3295 // setup Dynamic events 3296 $.each(options.triggerEventTypes, function (triggerType, events) { 3297 3298 $.each(events, function (eventId, triggers) { 3299 3300 switch (triggerType) { 3301 case 'url_click': 3302 //@see: Utils.setupURLClickEvents() 3303 break; 3304 3305 case 'css_click': 3306 Utils.setupCSSClickEvents(eventId, triggers); 3307 break; 3308 3309 case 'css_mouseover': 3310 Utils.setupMouseOverClickEvents(eventId, triggers); 3311 break; 3312 3313 case 'scroll_pos': 3314 Utils.setupScrollPosEvents(eventId, triggers); 3315 break; 3316 case 'comment': 3317 Utils.setupCommentEvents(eventId, triggers); 3318 break; 3319 } 3320 3321 }); 3322 3323 }); 3324 // setup WooCommerce events 3325 if (options.woo.enabled) { 3326 3327 // WooCommerce AddToCart 3328 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click") 3329 && options.woo.hasOwnProperty("addToCartCatchMethod") 3330 && options.woo.addToCartCatchMethod === "add_cart_js" 3331 ) { 3332 3333 // Loop, any kind of "simple" product, except external 3334 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 3335 3336 var product_id = $(this).data('product_id'); 3337 if (typeof product_id !== 'undefined') { 3338 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")) { 3339 var tmpEventID = pys_generate_token(); 3340 $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) { 3341 tag.eventID = tmpEventID; 3342 }); 3343 } 3344 if (typeof product_id !== 'undefined') { 3345 Facebook.onWooAddToCartOnButtonEvent(product_id); 3346 Analytics.onWooAddToCartOnButtonEvent(product_id); 3347 GTM.onWooAddToCartOnButtonEvent(product_id); 3348 Pinterest.onWooAddToCartOnButtonEvent(product_id); 3349 Bing.onWooAddToCartOnButtonEvent(product_id); 3350 Reddit.onWooAddToCartOnButtonEvent(product_id); 3351 } 3352 } 3353 }); 3354 3355 // Single Product 3356 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 3357 // $(document) not work 3358 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 3359 3360 var $button = $(this); 3361 3362 if ($button.hasClass('disabled')) { 3363 return; 3364 } 3365 3366 var $form = $button.closest('form'); 3367 3368 var product_type = Utils.PRODUCT_SIMPLE; 3369 3370 if ($form.length === 0) { 3371 return ; 3372 } else if ($form.hasClass('variations_form')) { 3373 product_type = Utils.PRODUCT_VARIABLE; 3374 } else if($form.hasClass('bundle_form')) { 3375 product_type = Utils.PRODUCT_BUNDLE; 3376 } else if($form.hasClass('grouped_form')) { 3377 product_type = Utils.PRODUCT_GROUPED; 3378 } 3379 3380 3381 3382 3383 var product_id; 3384 var qty; 3385 3386 if (product_type === Utils.PRODUCT_GROUPED) { 3387 qty = 1; 3388 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3389 } else if (product_type === Utils.PRODUCT_VARIABLE) { 3390 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3391 var qtyTag = $form.find('input[name="quantity"]'); 3392 if(qtyTag.length <= 0) { 3393 qtyTag = $form.find('select[name="quantity"]'); 3394 } 3395 qty = parseInt(qtyTag.val()); 3396 } else { 3397 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3398 var qtyTag = $form.find('input[name="quantity"]'); 3399 if(qtyTag.length <= 0) { 3400 qtyTag = $form.find('select[name="quantity"]'); 3401 } 3402 qty = parseInt(qtyTag.val()); 3403 } 3404 3405 if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){ 3406 var tmpEventID = pys_generate_token(); 3407 $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) { 3408 tag.eventID = tmpEventID; 3409 }); 3410 } 3411 3412 Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 3413 Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 3414 3415 GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 3416 3417 Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 3418 Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 3419 Reddit.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 3420 3421 }); 3422 3423 } 3424 3425 // WooCommerce RemoveFromCart 3426 if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) { 3427 3428 $('body').on('click', options.woo.removeFromCartSelector, function (e) { 3429 3430 var $a = $(e.currentTarget), 3431 href = $a.attr('href'); 3432 3433 // extract cart item hash from remove button URL 3434 var regex = new RegExp("[\\?&]remove_item=([^&#]*)"), 3435 results = regex.exec(href); 3436 3437 if (results !== null) { 3438 3439 var item_hash = results[1]; 3440 3441 if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) { 3442 var events = options.dynamicEvents["woo_remove_from_cart"][item_hash]; 3443 Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events) 3444 } 3445 3446 } 3447 3448 }); 3449 } 3450 } 3451 3452 // setup EDD events 3453 if (options.edd.enabled) { 3454 3455 // EDD AddToCart 3456 if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) { 3457 3458 $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) { 3459 3460 var $button = $(this); 3461 var $form = $button.closest('form'); 3462 var variable_price = $button.data('variablePrice'); // yes/no 3463 var price_mode = $button.data('priceMode'); // single/multi 3464 var ids = []; 3465 var quantities = []; 3466 var qty; 3467 var id; 3468 3469 if (variable_price === 'yes' && price_mode === 'multi') { 3470 3471 id = $form.find('input[name="download_id"]').val(); 3472 3473 // get selected variants 3474 $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) { 3475 ids.push(id + '_' + $(el).val()); 3476 }); 3477 3478 // get qty for selected variants 3479 $.each(ids, function (i, variant_id) { 3480 3481 var variant_index = variant_id.split('_', 2); 3482 qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val(); 3483 3484 if (typeof qty !== 'undefined') { 3485 quantities.push(qty); 3486 } else { 3487 quantities.push(1); 3488 } 3489 3490 }); 3491 3492 } else if (variable_price === 'yes' && price_mode === 'single') { 3493 3494 id = $form.find('input[name="download_id"]').val(); 3495 ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val()); 3496 3497 qty = $form.find('input[name="edd_download_quantity"]').val(); 3498 3499 if (typeof qty !== 'undefined') { 3500 quantities.push(qty); 3501 } else { 3502 quantities.push(1); 3503 } 3504 3505 } else { 3506 3507 ids.push($button.data('downloadId')); 3508 3509 qty = $form.find('input[name="edd_download_quantity"]').val(); 3510 3511 if (typeof qty !== 'undefined') { 3512 quantities.push(qty); 3513 } else { 3514 quantities.push(1); 3515 } 3516 } 3517 3518 // fire event for each download/variant 3519 $.each(ids, function (i, download_id) { 3520 3521 var q = parseInt(quantities[i]); 3522 var variant_index = download_id.toString().split('_', 2); 3523 var price_index; 3524 3525 if (variant_index.length === 2) { 3526 download_id = variant_index[0]; 3527 price_index = variant_index[1]; 3528 } 3529 3530 Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3531 Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3532 GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3533 Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3534 Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3535 Reddit.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3536 }); 3537 3538 }); 3539 3540 } 3541 3542 3543 // EDD RemoveFromCart 3544 if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) { 3545 3546 $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) { 3547 3548 var href = $(this).attr('href'); 3549 if(href) { 3550 var key = href.substring(href.indexOf('=') + 1).charAt(0); 3551 if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) { 3552 var events = options.dynamicEvents.edd_remove_from_cart[key]; 3553 Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events) 3554 } 3555 } 3556 }); 3557 3558 } 3559 3560 } 3561 3562 // setup Comment Event 3563 if (options.dynamicEvents.hasOwnProperty("automatic_event_c
3563omment") 3564 ) { 3565 3566 $('form.comment-form').on("submit",function () { 3567 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) { 3568 var pixels = Object.keys(options.dynamicEvents.automatic_event_comment); 3569 for (var i = 0; i < pixels.length; i++) { 3570 var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]); 3571 if ( pixels[i] !== 'reddit') { 3572 Utils.copyProperties(Utils.getRequestParams(), event.params); 3573 } 3574 getPixelBySlag(pixels[i]).onCommentEvent(event); 3575 } 3576 } 3577 }); 3578 3579 } 3580 3581 3582 // setup Form Event 3583 if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 3584 3585 $(document).onFirst('submit', 'form', function (e) { 3586 3587 var $form = $(this); 3588 3589 // exclude WP forms 3590 if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') { 3591 return; 3592 } 3593 3594 // exclude Woo forms 3595 if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') || 3596 $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) { 3597 return; 3598 } 3599 3600 // exclude EDD forms 3601 if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) { 3602 return; 3603 } 3604// exclude CF7 forms 3605 if ($form.hasClass('wpcf7-form')) { 3606 return; 3607 } 3608 // exclude Forminator forms 3609 if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) { 3610 return; 3611 } 3612 // exclude WPforms forms 3613 if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) { 3614 return; 3615 } 3616 // exclude Formidable forms 3617 /*if ($form.hasClass('frm-show-form')) { 3618 return; 3619 }*/ 3620 // exclude Ninja Forms forms 3621 if ($form.parent().hasClass('nf-form-layout')) { 3622 return; 3623 } 3624 // exclude Fluent forms 3625 if ($form.hasClass('frm-fluent-form')) { 3626 return; 3627 } 3628 if(!options.enable_success_send_form) { 3629 var params = { 3630 form_id: $form.attr('id'), 3631 form_class: $form.attr('class'), 3632 text: $form.find('[type="submit"]').is('input') ? 3633 $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text() 3634 }; 3635 3636 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 3637 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 3638 for (var i = 0; i < pixels.length; i++) { 3639 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 3640 3641 if (pixels[i] === "tiktok" || pixels[i] === "reddit") { 3642 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3643 } else { 3644 Utils.copyProperties(params, event.params,) 3645 Utils.copyProperties(Utils.getRequestParam
3645s(), event.params); 3646 getPixelBySlag(pixels[i]).onFormEvent(event); 3647 } 3648 } 3649 } 3650 } 3651 }); 3652 3653 document.addEventListener( 'wpcf7mailsent', function( event ) { 3654 var form_id = event.detail.contactFormId; 3655 sendFormAction($(event.target), form_id); 3656 }, false ); 3657 //Forminator 3658 $(document).on( 'forminator:form:submit:success', function( event ){ 3659 var form_id = $(event.target).find('input[name="form_id"]').val(); 3660 sendFormAction($(event.target), form_id); 3661 }); 3662 3663 //WPForm 3664 $('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => { 3665 var form_id = $(event.target).attr('data-formid'); 3666 sendFormAction($(event.target), form_id); 3667 }) 3668 $(document).on( 'frmFormComplete', function( event, form, response ) { 3669 const form_id = $(form).find('input[name="form_id"]').val(); 3670 sendFormAction($(event.target), form_id); 3671 }); 3672 // Ninja Forms 3673 $(document).onFirst('nfFormSubmitResponse', function (event, data) { 3674 const form_id = data.response.data.form_id; 3675 sendFormAction($(event.target), form_id); 3676 }); 3677 3678 var fluentForms = $('form.frm-fluent-form'); 3679 fluentForms.each(function() { 3680 var $form = $(this); 3681 $form.on('fluentform_submission_success', function(event) { 3682 var $formItem = $(this); 3683 var form_id = $formItem.attr('data-form_id'); 3684 sendFormAction($(event.target), form_id); 3685 }); 3686 }); 3687 3688 } 3689 3690 3691 // load pixel APIs 3692 Utils.loadPixels(); 3693 // setup Enrich content 3694 if(Utils.isCheckoutPage()) { 3695 Utils.addCheckoutFields(); 3696 } 3697 }); 3698 3699 var sendFormAction = function (form_target, formId){ 3700 var params = { 3701 form_id: formId, 3702 text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() : 3703 form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() : 3704 form_target.find('[type="submit"]').text() 3705 }; 3706 3707 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 3708 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 3709 for (var i = 0; i < pixels.length; i++) { 3710 var event = options.dynamicEvents.automatic_event_form[pixels[i]]; 3711 if (pixels[i] === "tiktok" || pixels[i] === "reddit") { 3712 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3713 } else { 3714 Utils.copyProperties(params, event.params)
3715 Utils.copyProperties(Utils.getRequestParams(), event.params); 3716 getPixelBySlag(pixels[i]).onFormEvent(event); 3717 } 3718 } 3719 } 3720 } 3721 3722}(jQuery, pysOptions); 3723 3724function pys_generate_token() { 3725 return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => 3726 (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) 3727 ); 3728} 3729 3730function getBundlePriceOnSingleProduct(data) { 3731 var items_sum = 0; 3732 jQuery(".bundle_form .bundled_product").each(function(index){ 3733 var id = jQuery(this).find(".cart").data("bundled_item_id"); 3734 var item_price = data.prices[id]; 3735 var item_quantity = jQuery(this).find(".bundled_qty").val(); 3736 if(!jQuery(this).hasClass("bundled_item_optional") || 3737 jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) { 3738 items_sum += item_price*item_quantity; 3739 } 3740 }); 3741 return items_sum; 3742} 3743function getUrlParameter(sParam) { 3744 var sPageURL = window.location.search.substring(1), 3745 sURLVariables = sPageURL.split('&'), 3746 sParameterName, 3747 i; 3748 3749 for (i = 0; i < sURLVariables.length; i++) { 3750 sParameterName = sURLVariables[i].split('='); 3751 3752 if (sParameterName[0] === sParam) { 3753 return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 3754 } 3755 } 3756 return false; 3757}; 3758function getCookieYes(key) { 3759 const cookiesObj = document.cookie 3760 .split(";") 3761 .reduce((ac, cv) => { 3762 const [k, v] = cv.split("="); 3763 if (k && v) ac[k.trim()] = v; 3764 return ac; 3765 }, {}); 3766 const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"]; 3767 if (!consentCookie) return undefined; 3768 const { [key]: value } = consentCookie 3769 .split(",") 3770 .reduce((obj, pair) => { 3771 const [k, v] = pair.split(":"); 3772 if (k && v) obj[k] = v; 3773 return obj; 3774 }, {}); 3775 return value; 3776} 3777function getRootDomain(useSubdomain = false) { 3778 const hostname = window.location.hostname; // Get the current hostname 3779 // Check if tldjs is defined before using it 3780 if (typeof tldjs === "undefined") { 3781 console.warn("tldjs is not defined"); 3782 return hostname; // Return hostname as a fallback 3783 } 3784 3785 const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain 3786 3787 // Return the root domain with or without a leading dot based on useSubdomain 3788 return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname; 3789}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.