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