1/* global pysOptions */ 2 3// https://bitbucket.org/pixelyoursite/pys_pro_7/issues/7/possible-ie-11-error 4// https://tc39.github.io/ecma262/#sec-array.prototype.includes 5if (!Array.prototype.includes) { 6 Object.defineProperty(Array.prototype, 'includes', { 7 value: function (searchElement, fromIndex) { 8 9 if (this == null) { 10 throw new TypeError('"this" is null or not defined'); 11 } 12 13 // 1. Let O be ? ToObject(this value). 14 var o = Object(this); 15 16 // 2. Let len be ? ToLength(? Get(O, "length")). 17 var len = o.length >>> 0; 18 19 // 3. If len is 0, return false. 20 if (len === 0) { 21 return false; 22 } 23 24 // 4. Let n be ? ToInteger(fromIndex). 25 // (If fromIndex is undefined, this step produces the value 0.) 26 var n = fromIndex | 0; 27 28 // 5. If n ⥠0, then 29 // a. Let k be n. 30 // 6. Else n < 0, 31 // a. Let k be len + n. 32 // b. If k < 0, let k be 0. 33 var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); 34 35 function sameValueZero(x, y) { 36 return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)); 37 } 38 39 // 7. Repeat, while k < len 40 while (k < len) { 41 // a. Let elementK be the result of ? Get(O, ! ToString(k)). 42 // b. If SameValueZero(searchElement, elementK) is true, return true. 43 if (sameValueZero(o[k], searchElement)) { 44 return true; 45 } 46 // c. Increase k by 1. 47 k++; 48 } 49 50 // 8. Return false 51 return false; 52 } 53 }); 54} 55 56!function ($, options) { 57 58 if (options.debug) { 59 console.log('PYS:', options); 60 } 61 62 var dummyPinterest = function () { 63 64 /** 65 * Public API 66 */ 67 return { 68 69 isEnabled: function () { 70 }, 71 72 disable: function () { 73 }, 74 75 loadPixel: function () { 76 }, 77 78 fireEvent: function (name, data) { 79 return false; 80 }, 81 82 onCommentEvent: function () { 83 }, 84 85 onDownloadEvent: function (params) { 86 }, 87 88 onFormEvent: function (params) { 89 }, 90 91 onWooAddToCartOnButtonEvent: function (product_id) { 92 }, 93 94 onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) { 95 }, 96 97 onWooRemoveFromCartEvent: function (cart_item_hash) { 98 }, 99 100 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 101 }, 102 103 onEddRemoveFromCartEvent: function (item) { 104 }, 105 onPageScroll: function (event) {}, 106 onTime: function (event) { 107 108 }, 109 110 } 111 112 }(); 113 114 var dummyBing = function () { 115 116 /** 117 * Public API 118 */ 119 return { 120 121 isEnabled: function () { 122 }, 123 124 disable: function () { 125 }, 126 127 loadPixel: function () { 128 }, 129 130 fireEvent: function (name, data) { 131 return false; 132 }, 133 134 onAdSenseEvent: function () { 135 }, 136 137 onClickEvent: function (params) { 138 }, 139 140 onWatchVideo: function (params) { 141 }, 142 143 onCommentEvent: function () { 144 }, 145 146 onFormEvent: function (params) { 147 }, 148 149 onDownloadEvent: function (params) { 150 }, 151 152 onWooAddToCartOnButtonEvent: function (product_id) { 153 }, 154 155 onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) { 156 }, 157 158 onWooRemoveFromCartEvent: function (cart_item_hash) { 159 }, 160 161 onWooAffiliateEvent: function (product_id) { 162 }, 163 164 onWooPayPalEvent: function () { 165 }, 166 167 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 168 }, 169 170 onEddRemoveFromCartEvent: function (item) { 171 }, 172 173 onPageScroll: function (event) { 174 }, 175 176 onTime: function (event) { 177 }, 178 179 } 180 181 }(); 182 183 var Utils = function (options) { 184 185 var Pinterest = dummyPinterest; 186 187 var Bing = dummyBing; 188 189 var gtag_loaded = false;
190 191 let isNewSession = checkSession(); 192 193 var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; 194 195 var utmId = ['fbadid', 'gadid', 'padid', 'bingid']; 196 197 function validateEmail(email) { 198 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,}))$/; 199 return re.test(email); 200 } 201 function getDomain(url) { 202 203 url = url.replace(/(https?:\/\/)?(www.)?/i, ''); 204 205 if (url.indexOf('/') !== -1) { 206 return url.split('/')[0]; 207 } 208 209 return url; 210 } 211 function loadPixels() { 212 213 if (!options.gdpr.all_disabled_by_api) { 214 215 if (!options.gdpr.facebook_disabled_by_api) { 216 Facebook.loadPixel(); 217 } 218 219 if (!options.gdpr.analytics_disabled_by_api) { 220 Analytics.loadPixel(); 221 } 222 223 if (!options.gdpr.pinterest_disabled_by_api) { 224 Pinterest.loadPixel(); 225 } 226 227 if (!options.gdpr.bing_disabled_by_api) { 228 Bing.loadPixel(); 229 } 230 } 231 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 232 if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) { 233 Analytics.loadPixel(); 234 } 235 } 236 237 } 238 239 function checkSession() { 240 let duration = options.last_visit_duration * 60000 241 if( Cookies.get('pys_start_session') === undefined || 242 Cookies.get('pys_session_limit') === undefined) { 243 var now = new Date(); 244 now.setTime(now.getTime() + duration); 245 Cookies.set('pys_session_limit', true,{ expires: now }) 246 Cookies.set('pys_start_session', true) 247 return true 248 } 249 return false 250 251 } 252 253 function getTrafficSource() { 254 255 try { 256 257 let referrer = document.referrer.toString(), 258 source; 259 260 let direct = referrer.length === 0; 261 let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0; 262 let external = !direct && !internal; 263 264 if (external === false) { 265 source = 'direct'; 266 } else { 267 source = referrer; 268 } 269 270 if (source !== 'direct') { 271 // leave only domain (Issue #70) 272 return getDomain(source); 273 } else { 274 return source; 275 } 276 277 } catch (e) { 278 console.error(e); 279 return 'direct'; 280 } 281 282 } 283 284 /** 285 * Return query variables object with where property name is query variable 286 * and property value is query variable value. 287 */ 288 function getQueryVars() { 289 290 try { 291 292 var result = {}, 293 tmp = []; 294 295 window.location.search 296 .substr(1) 297 .split("&") 298 .forEach(function (item) { 299 300 tmp = item.split('='); 301 302 if (tmp.length > 1) { 303 result[tmp[0]] = tmp[1]; 304 } 305 306 }); 307 308 return result; 309 310 } catch (e) { 311 console.error(e); 312 return {}; 313 } 314 315 } 316 317 318 function getUTMId(useLast = false) { 319 try { 320 let cookiePrefix = 'pys_' 321 let terms = []; 322 if (useLast) { 323 cookiePrefix = 'last_pys_' 324 } 325 $.each(utmId, function (index, name) { 326 if (Cookies.get(cookiePrefix + name)) { 327 terms[name] = Cookies.get(cookiePrefix + name) 328 } 329 }); 330 return terms; 331 } catch (e) { 332 console.error(e); 333 return []; 334 } 335 } 336 /** 337 * Return UTM terms from request query variables or from cookies. 338 */ 339 function getUTMs(useLast = false) { 340 341 try { 342 let cookiePrefix = 'pys_' 343 if(useLast) { 344 cookiePrefix = 'last_pys_' 345 } 346 let terms = []; 347 $.each(utmTerms, function (index, name) { 348 if (Cookies.get(cookiePrefix + name)) { 349 let value = Cookies.get(cookiePrefix + name); 350 terms[name] = filterEmails(value); // do not allow email in request params (Issue #70) 351 } 352 }); 353 354 return terms; 355 356 } catch (e) { 357 console.error(e); 358 return []; 359 } 360 361 } 362 363 function getDateTime() { 364 var dateTime = new Array(); 365 var date = new Date(), 366 days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 367 months = ['January', 'February', 'March', 'April', 'May', 'June', 368 'July', 'August', 'September', 'October', 'November', 'December' 369 ], 370 hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08', 371 '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17', 372 '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24' 373 ]; 374 dateTime.push(hours[date.getHours()]); 375 dateTime.push(days[date.getDay()]); 376 dateTime.push(months[date.getMonth()]); 377 return dateTime; 378 } 379 380 function filterEmails(value) { 381 return validateEmail(value) ? undefined : value; 382 } 383 384 /** 385 * PUBLIC API 386 */ 387 return { 388 PRODUCT_SIMPLE : 0, 389 PRODUCT_VARIABLE : 1, 390 PRODUCT_BUNDLE : 2, 391 PRODUCT_GROUPED : 3, 392 393 fireEventForAllPixel:function(functionName,events){ 394 if (events.hasOwnProperty(Facebook.tag())) 395 Facebook[functionName](events[Facebook.tag()]); 396 if (events.hasOwnProperty(Analytics.tag())) 397 Analytics[functionName](events[Analytics.tag()]); 398 if (events.hasOwnProperty(Pinterest.tag())) 399 Pinterest[functionName](events[Pinterest.tag()]); 400 if (events.hasOwnProperty(Bing.tag())) 401 Bing[functionName](events[Bing.tag()]); 402 }, 403 404 setupPinterestObject: function () { 405 Pinterest = window.pys.Pinterest || Pinterest; 406 return Pinterest; 407 }, 408 409 setupBingObject: function () { 410 Bing = window.pys.Bing || Bing; 411 return Bing; 412 }, 413 414 // Clone all object members to another and return it 415 copyProperties: function (from, to) { 416 for (var key in from) { 417 if("function" == typeof from[key]) { 418 continue; 419 } 420 to[key] = from[key]; 421 } 422 return to; 423 }, 424 425 manageCookies: function () { 426 let expires = parseInt(options.cookie_duration); // days 427 let queryVars = getQueryVars(); 428 let landing = window.location.href.split('?')[0]; 429 try { 430 // save data for first visit 431 if(Cookies.get('pys_first_visit') === undefined) { 432 Cookies.set('pys_first_visit', true, { expires: expires }); 433 Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires }); 434 Cookies.set('pys_landing_page',landing,{ expires: expires }); 435 $.each(utmTerms, function (index, name) { 436 if (queryVars.hasOwnProperty(name)) { 437 Cookies.set('pys_' + name, queryVars[name], { expires: expires }); 438 } else { 439 Cookies.remove('pys_' + name) 440 } 441 }); 442 $.each(utmId,function(index,name) { 443 if (queryVars.hasOwnProperty(name)) { 444 Cookies.set('pys_' + name, queryVars[name], { expires: expires }); 445 } else { 446 Cookies.remove('pys_' + name) 447 } 448 }) 449 } 450 451 // save data for last visit if it new session 452 if(isNewSession) { 453 Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires }); 454 $.each(utmTerms, function (index, name) { 455 if (queryVars.hasOwnProperty(name)) { 456 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires }); 457 } else { 458 Cookies.remove('last_pys_' + name) 459 } 460 }); 461 $.each(utmId,function(index,name) { 462 if (queryVars.hasOwnProperty(name)) { 463 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires }); 464 } else { 465 Cookies.remove('last_pys_' + name) 466 } 467 }) 468 Cookies.set('last_pys_landing_page',landing,{ expires: expires }); 469 } 470 } catch (e) { 471 console.error(e); 472 } 473 }, 474 // clone object 475 clone: function(obj) { 476 var copy; 477 478 // Handle the 3 simple types, and null or undefined 479 if (null == obj || "object" != typeof obj) return obj; 480 481 // Handle Date 482 if (obj instanceof Date) { 483 copy = new Date(); 484 copy.setTime(obj.getTime()); 485 return copy; 486 } 487 488 // Handle Array 489 if (obj instanceof Array) { 490 copy = []; 491 for (var i = 0, len = obj.length; i < len; i++) { 492 if("function" == typeof obj[i]) { 493 continue; 494 } 495 copy[i] = Utils.clone(obj[i]); 496 } 497 return copy; 498 } 499 500 // Handle Object 501 if (obj instanceof Object) { 502 copy = {}; 503 for (var attr in obj) { 504 if (obj.hasOwnProperty(attr)) { 505 if("function" == typeof obj[attr]) { 506 continue; 507 } 508 copy[attr] = Utils.clone(obj[attr]); 509 } 510 } 511 return copy; 512 } 513 514 return obj; 515 }, 516 517 // Returns array of elements with given tag name 518 getTagsAsArray: function (tag) { 519 return [].slice.call(document.getElementsByTagName(tag)); 520 }, 521
522 getRequestParams: function () { 523 return []; 524 }, 525 526 /** 527 * CUSTOM EVENTS 528 */ 529 530 setupMouseOverClickEvents: function (eventId, triggers) { 531 532 // Non-default binding used to avoid situations when some code in external js 533 // stopping events propagation, eg. returns false, and our handler will never called 534 document.addEventListener('mouseover', function(event) { 535 var matchedElements = Array.from(document.querySelectorAll(triggers)); 536 if (matchedElements.includes(event.target)) { 537 if (event.target.classList.contains('pys-mouse-over-' + eventId)) { 538 return true; 539 } else { 540 event.target.classList.add('pys-mouse-over-' + eventId); 541 } 542 543 Utils.fireTriggerEvent(eventId); 544 } 545 }); 546 547 }, 548 549 setupCSSClickEvents: function (eventId, triggers) { 550 // Non-default binding used to avoid situations when some code in external js 551 // stopping events propagation, eg. returns false, and our handler will never called 552 document.addEventListener('click', function(event) { 553 var matchedElements = Array.from(document.querySelectorAll(triggers)); 554 if (matchedElements.includes(event.target)) { 555 console.log(event.target) 556 Utils.fireTriggerEvent(eventId); 557 } 558 }, true); 559 }, 560 561 setupURLClickEvents: function () { 562 563 // Non-default binding used to avoid situations when some code in external js 564 // stopping events propagation, eg. returns false, and our handler will never called 565 $('a[data-pys-event-id]').onFirst('click', function (evt) { 566 567 $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) { 568 569 eventId = parseInt(eventId); 570 571 if (isNaN(eventId) === false) { 572 Utils.fireTriggerEvent(eventId); 573 } 574 575 }); 576 577 }); 578 579 580 }, 581 582 setupScrollPosEvents: function (eventId, triggers) { 583 584 var scrollPosThresholds = {}, 585 docHeight = $(document).height() - $(window).height(); 586 587 // convert % to absolute positions 588 $.each(triggers, function (index, scrollPos) { 589 590 // convert % to pixels 591 scrollPos = docHeight * scrollPos / 100; 592 scrollPos = Math.round(scrollPos); 593 594 scrollPosThresholds[scrollPos] = eventId; 595 596 }); 597 598 $(document).on("scroll",function () { 599 600 var scrollPos = $(window).scrollTop(); 601 602 $.each(scrollPosThresholds, function (threshold, eventId) { 603 604 // position has not reached yes 605 if (scrollPos <= threshold) { 606 return true; 607 } 608 609 // fire event only once 610 if (eventId === null) { 611 return true; 612 } else { 613 scrollPosThresholds[threshold] = null; 614 } 615 616 Utils.fireTriggerEvent(eventId); 617 618 }); 619 620 }); 621 622 623 }, 624 setupCommentEvents : function (eventId,triggers) { 625 $('form.comment-form').on("submit",function () { 626 Utils.fireTriggerEvent(eventId); 627 }); 628 }, 629 630 /** 631 * Events 632 */ 633 634 fireTriggerEvent: function (eventId) { 635 636 if (!options.triggerEvents.hasOwnProperty(eventId)) { 637 return; 638 } 639 640 var event = {}; 641 var events = options.triggerEvents[eventId]; 642 643 if (events.hasOwnProperty('facebook')) { 644 event = events.facebook; 645 Facebook.fireEvent(event.name, event); 646 } 647 648 if (events.hasOwnProperty('ga')) { 649 event = events.ga; 650 Analytics.fireEvent(event.name, event); 651 } 652 653 if (events.hasOwnProperty('pinterest')) { 654 event = events.pinterest; 655 Pinterest.fireEvent(event.name, event); 656 } 657 658 if (events.hasOwnProperty('bing')) { 659 event = events.bing; 660 Bing.fireEvent(event.name, event); 661 } 662 }, 663 664 fireStaticEvents: function (pixel) { 665 666 if (options.staticEvents.hasOwnProperty(pixel)) { 667 668 $.each(options.staticEvents[pixel], function (eventName, events) { 669 $.each(events, function (index, eventData) { 670 671 eventData.fired = eventData.fired || false; 672 673 if (!eventData.fired) { 674 675 var fired = false;
676 677 // fire event 678 if ('facebook' === pixel) { 679 fired = Facebook.fireEvent(eventData.name, eventData); 680 } else if ('ga' === pixel) { 681 fired = Analytics.fireEvent(eventData.name, eventData); 682 } else if ('pinterest' === pixel) { 683 fired = Pinterest.fireEvent(eventData.name, eventData); 684 } else if ('bing' === pixel) { 685 fired = Bing.fireEvent(eventData.name, eventData); 686 } 687 688 // prevent event double event firing 689 eventData.fired = fired; 690 691 } 692 693 }); 694 }); 695 696 } 697 698 }, 699 700 /** 701 * Load tag's JS 702 * 703 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/ 704 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 705 */ 706 loadGoogleTag: function (id) { 707 708 if (!gtag_loaded) { 709 710 (function (window, document, src) { 711 var a = document.createElement('script'), 712 m = document.getElementsByTagName('script')[0]; 713 a.async = 1; 714 a.src = src; 715 m.parentNode.insertBefore(a, m); 716 })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id); 717 718 window.dataLayer = window.dataLayer || []; 719 window.gtag = window.gtag || function gtag() { 720 dataLayer.push(arguments); 721 }; 722 723 gtag('js', new Date()); 724 725 gtag_loaded = true; 726 727 } 728 729 }, 730 731 /** 732 * GDPR 733 */ 734 735 loadPixels: function () { 736 737 if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) { 738 739 // retrieves actual PYS GDPR filters values which allow to avoid cache issues 740 $.get({ 741 url: options.ajaxUrl, 742 dataType: 'json', 743 data: { 744 action: 'pys_get_gdpr_filters_values' 745 }, 746 success: function (res) { 747 748 if (res.success) { 749 750 options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api; 751 options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api; 752 options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api; 753 options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api; 754 options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api; 755 options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api; 756 757 } 758 759 loadPixels(); 760 761 } 762 }); 763 764 } else { 765 loadPixels(); 766 } 767 768 }, 769 770 consentGiven: function (pixel) { 771 772 /** 773 * ConsentMagic 774 */ 775 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 776 777 var test_prefix = CS_Data.test_prefix; 778 if ((typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) && pixel == 'analytics') { 779 return true; 780 } 781 if ((typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1) && pixel == 'google_ads') { 782 return true; 783 } 784 785 if ( CS_Data.cs_cache_enabled == 1 ) { 786 var substring = "cs_enabled_cookie_term"; 787 var theCookies = document.cookie.split(';'); 788 789 for (var i = 1 ; i <= theCookies.length; i++) { 790 if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) { 791 var categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' ); 792 categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) ); 793 var cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie ); 794 795 if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) { 796 if ( cs_cookie_val == 'yes' ) { 797 return true; 798 } else { 799 return false;
800 } 801 } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) { 802 if ( cs_cookie_val == 'yes' ) { 803 return true; 804 } else { 805 return false; 806 } 807 } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) { 808 if ( cs_cookie_val == 'yes' ) { 809 return true; 810 } else { 811 return false; 812 } 813 } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) { 814 if ( cs_cookie_val == 'yes' ) { 815 return true; 816 } else { 817 return false; 818 } 819 } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) { 820 if ( cs_cookie_val == 'yes' ) { 821 return true; 822 } else { 823 return false; 824 } 825 } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) { 826 if ( cs_cookie_val == 'yes' ) { 827 return true; 828 } else { 829 return false; 830 } 831 } 832 } 833 } 834 } else { 835 var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix); 836 if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') { 837 return true; 838 } 839 } 840 841 return false; 842 843 } 844 845 /** 846 * Real Cookie Banner 847 */ 848 if(options.gdpr.real_cookie_banner_integration_enabled) { 849 var consentApi = window.consentApi; 850 if (consentApi) { 851 switch (pixel) { 852 case "analytics": 853 return consentApi.consentSync("http", "_ga", "*").cookieOptIn; 854 case "facebook": 855 return consentApi.consentSync("http", "_fbp", "*").cookieOptIn; 856 case "pinterest": 857 return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn; 858 default: 859 return true; 860 } 861 } 862 } 863 864 /** 865 * Cookiebot 866 */ 867 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 868 869 var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category']; 870 871 if (options.gdpr[pixel + '_prior_consent_enabled']) { 872 if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) { 873 return true; 874 } 875 } else { 876 if (Cookiebot.consent[cookiebot_consent_category]) { 877 return true; 878 } 879 } 880 881 return false; 882 883 } 884 885 /** 886 * Cookie Notice 887 */ 888 if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') { 889 890 var cn_cookie = Cookies.get(cnArgs.cookieName); 891 892 if (options.gdpr[pixel + '_prior_consent_enabled']) { 893 if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') { 894 return true; 895 } 896 } else { 897 if (cn_cookie === 'true') { 898 return true; 899 } 900 } 901 902 return false;
903 904 } 905 906 /** 907 * Cookie Law Info 908 */ 909 if (options.gdpr.cookie_law_info_integration_enabled) { 910 911 var cli_cookie = Cookies.get('viewed_cookie_policy'); 912 913 if (options.gdpr[pixel + '_prior_consent_enabled']) { 914 if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') { 915 return true; 916 } 917 } else { 918 if (cli_cookie === 'yes') { 919 return true; 920 } 921 } 922 923 return false; 924 925 } 926 927 return true; 928 929 }, 930 931 setupGdprCallbacks: function () { 932 /** 933 * ConsentMagic 934 */ 935 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 936 var test_prefix = CS_Data.test_prefix, 937 cs_refresh_after_consent = false, 938 substring = "cs_enabled_cookie_term"; 939 940 if (CS_Data.cs_refresh_after_consent == 1) { 941 cs_refresh_after_consent = CS_Data.cs_refresh_after_consent; 942 } 943 944 if (!cs_refresh_after_consent) { 945 var theCookies = document.cookie.split(';'); 946 for (var i = 1 ; i <= theCookies.length; i++) { 947 if (theCookies[i-1].indexOf(substring) !== -1) { 948 var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_',''); 949 categoryCookie = Number(categoryCookie.replace(/\D+/g,"")); 950 var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie); 951 if(cs_cookie_val == 'yes') { 952 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 953 Facebook.loadPixel(); 954 } 955 956 if (categoryCookie === CS_Data.cs_script_cat.bing) { 957 Bing.loadPixel(); 958 } 959 960 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)) { 961 962 Analytics.loadPixel(); 963 } 964 965 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 966 Pinterest.loadPixel(); 967 } 968 } else { 969 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 970 Facebook.disable(); 971 } 972 973 if (categoryCookie === CS_Data.cs_script_cat.bing) { 974 Bing.disable(); 975 } 976 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)) { 977 Analytics.disable(); 978 } 979 980 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 981 Pinterest.disable(); 982 } 983 } 984 if (Cookies.get('cs_enabled_advanced_matching') == 'yes') { 985 Facebook.loadPixel(); 986 } 987 } 988 } 989 990 $(document).on('click','.cs_action_btn',function(e) { 991 e.preventDefault(); 992 var elm = $(this), 993 button_action = elm.attr('data-cs_action'); 994 995 if(button_action === 'allow_all') { 996 Facebook.loadPixel(); 997 Bing.loadPixel(); 998 Analytics.loadPixel(); 999 Pinterest.loadPixel(); 1000 } else if(button_action === 'disable_all') { 1001 Facebook.disable(); 1002 Bing.disable(); 1003 if(CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined") 1004 { 1005 Analytics.disable(); 1006 } 1007 Pinterest.disable(); 1008 } 1009 }); 1010 } 1011 } 1012 /** 1013 * Real Cookie Banner 1014 */ 1015 if(options.gdpr.real_cookie_banner_integration_enabled) { 1016 var consentApi = window.consentApi; 1017 if (consentApi) { 1018 consentApi.consent("http", "_ga", "*") 1019 .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics)); 1020 consentApi.consent("http", "_fbp", "*") 1021 .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook)); 1022 consentApi.consent("http", "_pinterest_sess", ".pinterest.com") 1023 .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest)); 1024 } 1025 } 1026 /** 1027 * Cookiebot 1028 */ 1029 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1030 1031 window.addEventListener("CookiebotOnConsentReady", function() { 1032 if (Cookiebot.consent.marketing) { 1033 Facebook.loadPixel(); 1034 Bing.loadPixel(); 1035 Pinterest.loadPixel(); 1036 1037 } 1038 if (Cookiebot.consent.statistics) { 1039 Analytics.loadPixel(); 1040 } 1041 if (!Cookiebot.consent.marketing) { 1042 Facebook.disable(); 1043 Pinterest.disable(); 1044 Bing.disable() 1045 } 1046 if (!Cookiebot.consent.statistics) { 1047 Analytics.disable(); 1048 } 1049 }); 1050 1051 } 1052 1053 /** 1054 * Cookie Notice 1055 */ 1056 if (options.gdpr.cookie_notice_integration_enabled) { 1057 1058 $(document).onFirst('click', '.cn-set-cookie', function () { 1059 1060 if ($(this).data('cookie-set') === 'accept') { 1061 Facebook.loadPixel(); 1062 Analytics.loadPixel(); 1063 Pinterest.loadPixel(); 1064 Bing.loadPixel(); 1065 } else { 1066 Facebook.disable(); 1067 Analytics.disable(); 1068 Pinterest.disable(); 1069 Bing.disable(); 1070 } 1071 1072 }); 1073 1074 $(document).onFirst('click', '.cn-revoke-cookie', function () { 1075 Facebook.disable(); 1076 Analytics.disable(); 1077 Pinterest.disable(); 1078 Bing.disable(); 1079 }); 1080 1081 } 1082 1083 /** 1084 * Cookie Law Info 1085 */ 1086 if (options.gdpr.cookie_law_info_integration_enabled) { 1087 1088 $(document).onFirst('click', '#cookie_action_close_header', function () { 1089 Facebook.loadPixel(); 1090 Analytics.loadPixel(); 1091 Pinterest.loadPixel(); 1092 Bing.loadPixel(); 1093 }); 1094 1095 $(document).onFirst('click', '#cookie_action_close_header_reject', function () { 1096 Facebook.disable(); 1097 Analytics.disable(); 1098 Pinterest.disable(); 1099 Bing.disable(); 1100 }); 1101 1102 } 1103 1104 }, 1105 1106 /** 1107 * DOWNLOAD DOCS 1108 */ 1109 1110 getLinkExtension: function (link) { 1111 1112 // Remove anchor, query string and everything before last slash 1113 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1114 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1115 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1116 1117 // If there's a period left in the URL, then there's a extension 1118 if (link.length > 0 && link.indexOf('.') !== -1) { 1119 link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period 1120 return link; 1121 } else { 1122 return ""; 1123 } 1124 }, 1125 1126 getLinkFilename: function (link) { 1127 1128 // Remove anchor, query string and everything before last slash 1129 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1130 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1131 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1132 1133 // If there's a period left in the URL, then there's a extension 1134 if (link.length > 0 && link.indexOf('.') !== -1) { 1135 return link; 1136 } else { 1137 return ""; 1138 } 1139 }, 1140 /** 1141 * Enrich 1142 */ 1143 isCheckoutPage: function () { 1144 return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') || 1145 $('body').hasClass('edd-checkout'); 1146 }, 1147 addCheckoutFields : function() { 1148 var utm = ""; 1149 var utms = getUTMs() 1150 1151 $.each(utmTerms, function (index, name) { 1152 if(index > 0) { 1153 utm+="|"; 1154 } 1155 utm+=name+":"+utms[name]; 1156 }); 1157 var utmIdList = ""; 1158 var utmsIds = getUTMId() 1159 $.each(utmId, function (index, name) { 1160 if(index > 0) { 1161 utmIdList+="|"; 1162 } 1163 utmIdList+=name+":"+utmsIds[name]; 1164 }); 1165 var utmIdListLast = ""; 1166 var utmsIdsLast = getUTMId(true) 1167 $.each(utmId, function (index, name) { 1168 if(index > 0) { 1169 utmIdListLast+="|"; 1170 } 1171 utmIdListLast+=name+":"+utmsIdsLast[name]; 1172 }); 1173 1174 1175 var utmLast = ""; 1176 var utmsLast = getUTMs(true) 1177 $.each(utmTerms, function (index, name) { 1178 if(index > 0) { 1179 utmLast+="|"; 1180 }
1181 utmLast+=name+":"+utmsLast[name]; 1182 }); 1183 1184 var dateTime = getDateTime(); 1185 var landing = Cookies.get('pys_landing_page'); 1186 var lastLanding = Cookies.get('last_pys_landing_page'); 1187 var trafic = Cookies.get('pysTrafficSource'); 1188 var lastTrafic = Cookies.get('last_pysTrafficSource'); 1189 1190 var $form = null; 1191 if($('body').hasClass('woocommerce-checkout')) { 1192 $form = $("form.woocommerce-checkout"); 1193 } else { 1194 $form = $("#edd_purchase_form"); 1195 } 1196 var inputs = {'pys_utm':utm, 1197 'pys_utm_id':utmIdList, 1198 'pys_browser_time':dateTime.join("|"), 1199 'pys_landing':landing, 1200 'pys_source':trafic, 1201 'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal", 1202 1203 'last_pys_landing':lastLanding, 1204 'last_pys_source':lastTrafic, 1205 'last_pys_utm':utmLast, 1206 'last_pys_utm_id':utmIdListLast, 1207 } 1208 1209 Object.keys(inputs).forEach(function(key,index) { 1210 $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> "); 1211 }); 1212 1213 1214 } 1215 }; 1216 1217 }(options); 1218 1219 var Facebook = function (options) { 1220 1221 1222 var defaultEventTypes = [ 1223 'PageView', 1224 'ViewContent', 1225 'Search', 1226 'AddToCart', 1227 'AddToWishlist', 1228 'InitiateCheckout', 1229 'AddPaymentInfo', 1230 'Purchase', 1231 'Lead', 1232 1233 'Subscribe', 1234 'CustomizeProduct', 1235 'FindLocation', 1236 'StartTrial', 1237 'SubmitApplication', 1238 'Schedule', 1239 'Contact', 1240 'Donate' 1241 ]; 1242 1243 var initialized = false; 1244 1245 // fire server side event gdpr plugin installed 1246 var isApiDisabled = options.gdpr.all_disabled_by_api || 1247 options.gdpr.facebook_disabled_by_api || 1248 options.gdpr.cookiebot_integration_enabled || 1249 options.gdpr.consent_magic_integration_enabled || 1250 options.gdpr.cookie_notice_integration_enabled || 1251 options.gdpr.cookie_law_info_integration_enabled; 1252 1253 /** 1254 * 1255 * @param allData 1256 * @param params 1257 * @returns {string | null} 1258 */ 1259 function sendFbServerEvent(allData,name,params) { 1260 let eventId = null; 1261 if(options.facebook.serverApiEnabled) { 1262 1263 if(allData.e_id === "woo_remove_from_cart" || allData.e_id === "woo_add_to_cart_on_button_click") {// server event will sended from hook 1264 let isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod") 1265 && options.woo.addToCartCatchMethod === "add_cart_js"; 1266 1267 if(isAddToCartFromJs || allData.e_id !== "woo_add_to_cart_on_button_click") { 1268 Facebook.updateEventId(allData.name); 1269 allData.eventID = Facebook.getEventId(allData.name); 1270 } else { 1271 // not update eventID for woo_add_to_cart_on_button_click, 1272 // web event created by ajax from server 1273 } 1274 } else { 1275 if( options.facebook.ajaxForServerEvent 1276 || isApiDisabled 1277 || allData.delay > 0 1278 || allData.type !== "static") 1279 { // send event from server if they was bloc by gdpr or need send with delay 1280 allData.eventID = pys_generate_token(36); 1281 var json = { 1282 action: 'pys_api_event', 1283 pixel: 'facebook', 1284 event: name, 1285 data:params, 1286 ids:options.facebook.pixelIds, 1287 eventID:allData.eventID, 1288 url:window.location.href, 1289 ajax_event:options.ajax_event 1290 }; 1291 if(allData.hasOwnProperty('woo_order')) { 1292 json['woo_order'] = allData.woo_order; 1293 } 1294 if(allData.hasOwnProperty('edd_order')) { 1295 json['edd_order'] = allData.edd_order; 1296 } 1297 1298 if(name == 'PageView') { 1299 let expires = parseInt(options.cookie_duration); 1300 var currentTimeInSeconds=Date.now(); 1301 var randomNum = Math.floor(1000000000 + Math.random() * 9000000000); 1302 timeoutDelay = 0; 1303 if(allData.delay > 0) 1304 { 1305 timeoutDelay = allData.delay; 1306 } 1307 if(!Cookies.get('_fbp')) 1308 { 1309 timeoutDelay = 100; 1310 } 1311 if(getUrlParameter('fbclid') && !Cookies.get('_fbc')) 1312 { 1313 timeoutDelay = 100; 1314 } 1315 setTimeout(function(){ 1316 if(!Cookies.get('_fbp')) 1317 { 1318 Cookies.set('_fbp','fb.1.'+currentTimeInSeconds+'.'+randomNum, { expires: expires }) 1319 } 1320 if(getUrlParameter('fbclid') && !Cookies.get('_fbc')) 1321 { 1322 Cookies.set('_fbc', 'fb.1.'+currentTimeInSeconds+'.'+getUrlParameter('fbclid'), { expires: expires }) 1323 } 1324 jQuery.ajax( { 1325 type: 'POST', 1326 url: options.ajaxUrl, 1327 data: json, 1328 headers: { 1329 'Cache-Control': 'no-cache' 1330 }, 1331 success: function(){}, 1332 }); 1333 },timeoutDelay) 1334 } 1335 else 1336 { 1337 jQuery.ajax( { 1338 type: 'POST', 1339 url: options.ajaxUrl, 1340 data: json, 1341 headers: { 1342 'Cache-Control': 'no-cache' 1343 }, 1344 success: function(){}, 1345 }); 1346 } 1347 } 1348 } 1349 eventId = allData.eventID 1350 } 1351 1352 return eventId; 1353 } 1354 1355 function fireEvent(name, allData) { 1356 1357 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) { 1358 return; 1359 } 1360 1361 var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom'; 1362 var data = allData.params; 1363 var params = {}; 1364 var arg = {}; 1365 Utils.copyProperties(data, params); 1366 1367 let eventId = sendFbServerEvent(allData,name,params) 1368 1369 1370 if("hCR" === name) { 1371 return; 1372 } 1373 1374 if (options.debug) { 1375 console.log('[Facebook] ' + name, params,"eventID",eventId); 1376 } 1377 1378 if(eventId != null) { 1379 arg.eventID = eventId; 1380 } 1381 1382 fbq(actionType, name, params,arg); 1383 } 1384 1385 /** 1386 * Public API 1387 */ 1388 return { 1389 tag: function() { 1390 return "facebook"; 1391 }, 1392 isEnabled: function () { 1393 return options.hasOwnProperty('facebook'); 1394 }, 1395 1396 disable: function () { 1397 initialized = false;
1398 }, 1399 1400 /** 1401 * Load pixel's JS 1402 */ 1403 loadPixel: function () { 1404 1405 if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) { 1406 return; 1407 } 1408 1409 !function (f, b, e, v, n, t, s) { 1410 if (f.fbq) return; 1411 n = f.fbq = function () { 1412 n.callMethod ? 1413 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 1414 }; 1415 if (!f._fbq) f._fbq = n; 1416 n.push = n; 1417 n.loaded = !0; 1418 n.version = '2.0'; 1419 n.agent = 'dvpixelyoursite'; 1420 n.queue = []; 1421 t = b.createElement(e); 1422 t.async = !0; 1423 t.src = v; 1424 s = b.getElementsByTagName(e)[0]; 1425 s.parentNode.insertBefore(t, s) 1426 }(window, 1427 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 1428 1429 // initialize pixel 1430 options.facebook.pixelIds.forEach(function (pixelId) { 1431 1432 if (options.facebook.removeMetadata) { 1433 fbq('set', 'autoConfig', false, pixelId); 1434 } 1435 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 1436 if(options.facebook.advancedMatching.length === 0) { 1437 fbq('init', pixelId); 1438 } else { 1439 var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix); 1440 if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) { 1441 if (cs_advanced_matching == 'yes') { 1442 fbq('init', pixelId, options.facebook.advancedMatching); 1443 } else { 1444 fbq('init', pixelId); 1445 } 1446 } else { 1447 fbq('init', pixelId, options.facebook.advancedMatching); 1448 } 1449 } 1450 } else { 1451 if (options.facebook.advancedMatching.length === 0) { 1452 fbq('init', pixelId); 1453 } else { 1454 fbq('init', pixelId, options.facebook.advancedMatching); 1455 } 1456 } 1457 }); 1458 1459 initialized = true; 1460 1461 Utils.fireStaticEvents('facebook'); 1462 1463 }, 1464 1465 fireEvent: function (name, data) { 1466 1467 if (!initialized || !this.isEnabled()) { 1468 return false; 1469 } 1470 1471 data.delay = data.delay || 0; 1472 data.params = data.params || {}; 1473 1474 if (data.delay === 0) { 1475 1476 fireEvent(name, data); 1477 1478 } else { 1479 1480 setTimeout(function (name, params) { 1481 fireEvent(name, params); 1482 }, data.delay * 1000, name, data); 1483 1484 } 1485 1486 return true; 1487 1488 }, 1489 1490 onCommentEvent: function (event) { 1491 this.fireEvent(event.name, event); 1492 }, 1493 1494 onDownloadEvent: function (event) { 1495 this.fireEvent(event.name, event); 1496 }, 1497 1498 onFormEvent: function (event) { 1499 1500 this.fireEvent(event.name, event); 1501 1502 }, 1503 1504 onWooAddToCartOnButtonEvent: function (product_id) { 1505 1506 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1507 return; 1508 var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]; 1509 1510 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1511 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 1512 event = Utils.copyProperties(event, {}) 1513 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params) 1514 this.fireEvent(event.name, event); 1515 } 1516 } 1517 }, 1518 1519 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 1520 1521 window.pysWooProductData = window.pysWooProductData || []; 1522 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1523 return; 1524 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1525 1526 if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) { 1527 product_id = parseInt($form.find('input[name="variation_id"]').val()); 1528 } 1529 1530 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1531 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 1532 1533 1534 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params); 1535 1536 var groupValue = 0; 1537 if(product_type === Utils.PRODUCT_GROUPED ) { 1538 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 1539 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 1540 var quantity = parseInt($(this).val()); 1541 if(isNaN(quantity)) { 1542 quantity = 0; 1543 } 1544 var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId]; 1545 1546 if(quantity == 0) { 1547 event.params.content_ids.forEach(function(el,index,array) { 1548 if(el == childItem.content_id) { 1549 array.splice(index, 1); 1550 } 1551 }); 1552 } 1553 1554 if(event.params.hasOwnProperty('contents')) { 1555 event.params.contents.forEac
1555h(function(el,index,array) { 1556 if(el.id == childItem.content_id) { 1557 if(quantity > 0){ 1558 el.quantity = quantity; 1559 } else { 1560 array.splice(index, 1); 1561 } 1562 } 1563 }); 1564 } 1565 1566 1567 groupValue += childItem.price * quantity; 1568 }); 1569 if(groupValue == 0) return; // skip if no items selected 1570 } 1571 1572 // maybe customize value option 1573 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 1574 1575 if(product_type === Utils.PRODUCT_GROUPED) { 1576 event.params.value = groupValue; 1577 } else if(product_type === Utils.PRODUCT_BUNDLE) { 1578 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 1579 var items_sum = getBundlePriceOnSingleProduct(data); 1580 event.params.value = (parseInt(data.base_price) + items_sum )* qty; 1581 } else { 1582 event.params.value = event.params.value * qty; 1583 } 1584 } 1585 1586 // only when non Facebook for WooCommerce logic used 1587 if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) { 1588 event.params.contents[0].quantity = qty; 1589 } 1590 1591 this.fireEvent(event.name, event); 1592 1593 } 1594 } 1595 }, 1596 1597 onWooRemoveFromCartEvent: function (event) { 1598 this.fireEvent(event.name, event); 1599 }, 1600 1601 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 1602 1603 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1604 return; 1605 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 1606 1607 if (window.pysEddProductData.hasOwnProperty(download_id)) { 1608 1609 var index; 1610 1611 if (price_index) { 1612 index = download_id + '_' + price_index; 1613 } else { 1614 index = download_id; 1615 } 1616 1617 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 1618 if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) { 1619 1620 1621 Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params) 1622 1623 // maybe customize value option 1624 if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') { 1625 event.params.value = event.params.value * qty; 1626 } 1627 1628 // update contents qty param 1629 var contents = event.params.contents; 1630 contents[0].quantity = qty; 1631 event.params.contents = contents; 1632 1633 this.fireEvent(event.name,event); 1634 1635 } 1636 } 1637 1638 } 1639 1640 }, 1641 1642 onEddRemoveFromCartEvent: function (event) { 1643 this.fireEvent(event.name, event); 1644 }, 1645 onPageScroll: function (event) { 1646 this.fireEvent(event.name, event); 1647 }, 1648 onTime: function (event) { 1649 this.fireEvent(event.name, event); 1650 },
1651 initEventIdCookies: function (key) { 1652 var ids = {}; 1653 ids[key] = pys_generate_token(36) 1654 Cookies.set('pys_fb_event_id', JSON.stringify(ids)); 1655 }, 1656 updateEventId:function(key) { 1657 var cooData = Cookies.get("pys_fb_event_id") 1658 if(cooData === undefined) { 1659 this.initEventIdCookies(key); 1660 } else { 1661 var data = JSON.parse(cooData); 1662 data[key] = pys_generate_token(36); 1663 Cookies.set('pys_fb_event_id', JSON.stringify(data) ); 1664 } 1665 }, 1666 1667 getEventId:function (key) { 1668 var data = Cookies.get("pys_fb_event_id"); 1669 if(data === undefined) { 1670 this.initEventIdCookies(key); 1671 data = Cookies.get("pys_fb_event_id"); 1672 } 1673 return JSON.parse(data)[key]; 1674 }, 1675 }; 1676 1677 }(options); 1678 1679 var Analytics = function (options) { 1680 1681 var initialized = false; 1682 1683 /** 1684 * Fires event 1685 * 1686 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 1687 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 1688 * @link: https://developers.google.com/gtagjs/reference/event 1689 * @link: https://developers.google.com/gtagjs/reference/parameter 1690 * 1691 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 1692 * 1693 * @param name 1694 * @param data 1695 */ 1696 function fireEvent(name, data) { 1697 1698 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) { 1699 return; 1700 } 1701 1702 var eventParams = Utils.copyProperties(data, {}); 1703 1704 var _fireEvent = function (tracking_id,name,params) { 1705 1706 params['send_to'] = tracking_id; 1707 1708 if (options.debug) { 1709 console.log('[Google Analytics #' + tracking_id + '] ' + name, params); 1710 } 1711 1712 gtag('event', name, params); 1713 1714 }; 1715 1716 options.ga.trackingIds.forEach(function (tracking_id) { 1717 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it 1718 var params = mapParamsTov4(tracking_id,name,copyParams) 1719 _fireEvent(tracking_id,name,params); 1720 }); 1721 1722 } 1723 function mapParamsTov4(tag,name,param) { 1724 //GA4 automatically collects a number of parameters for all events 1725 delete param.page_title; 1726 delete param.event_url; 1727 delete param.landing_page; 1728 // end 1729 if(isv4(tag)) { 1730 delete param.traffic_source; 1731 delete param.event_category; 1732 delete param.event_label; 1733 delete param.ecomm_prodid; 1734 delete param.ecomm_pagetype; 1735 delete param.ecomm_totalvalue; 1736 delete param.non_interaction; 1737 if(name === 'search') { 1738 param['search'] = param.search_term; 1739 delete param.search_term; 1740 delete param.non_interaction; 1741 delete param.dynx_itemid; 1742 delete param.dynx_pagetype; 1743 delete param.dynx_totalvalue; 1744 } 1745 } else { 1746 1747 switch (name) { 1748 1749 case 'Comment' : 1750 case 'login' : 1751 case 'sign_up' : 1752 case 'EmailClick' : 1753 case 'TelClick' : { 1754 let params = { 1755 event_category: "Key Actions", 1756 event_action: name, 1757 non_interaction: param.non_interaction, 1758 } 1759 return params; 1760 } 1761 case 'Form' : { 1762 let params = { 1763 event_category: "Key Actions", 1764 event_action: name,
1765 non_interaction: param.non_interaction, 1766 } 1767 var formClass = (typeof param.form_class != 'undefined') ? 'class: ' + param.form_class : ''; 1768 if(formClass != "") { 1769 params["event_label"] = formClass; 1770 } 1771 return params; 1772 } 1773 case 'Download' : { 1774 let params = { 1775 event_category: "Key Actions", 1776 event_action: name, 1777 event_label: param.download_name, 1778 non_interaction: param.non_interaction, 1779 } 1780 return params; 1781 } 1782 case 'TimeOnPage' : 1783 case 'PageScroll' : { 1784 let params = { 1785 event_category: "Key Actions", 1786 event_action: name, 1787 event_label: document.title, 1788 non_interaction: param.non_interaction, 1789 } 1790 return params; 1791 } 1792 case 'search' : { 1793 let params = { 1794 event_category: "Key Actions", 1795 event_action: name, 1796 event_label: param.search_term, 1797 non_interaction: param.non_interaction, 1798 } 1799 return params; 1800 } 1801 } 1802 1803 //delete standard params 1804 1805 delete param.post_type; 1806 delete param.post_id; 1807 delete param.plugin; 1808 delete param.user_role; 1809 delete param.cartlows; 1810 delete param.cartflows_flow; 1811 delete param.cartflows_step; 1812 } 1813 return param; 1814 } 1815 1816 function isv4(tag) { 1817 return tag.indexOf('G') === 0; 1818 } 1819 1820 /** 1821 * Public API 1822 */ 1823 return { 1824 tag: function() { 1825 return "ga"; 1826 }, 1827 isEnabled: function () { 1828 return options.hasOwnProperty('ga'); 1829 }, 1830 1831 disable: function () { 1832 initialized = false; 1833 }, 1834 1835 loadPixel: function () { 1836 1837 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 1838 return; 1839 } 1840 1841 Utils.loadGoogleTag(options.ga.trackingIds[0]); 1842 1843 var config = { 1844 'link_attribution': options.ga.enhanceLinkAttr, 1845 'anonymize_ip': options.ga.anonimizeIP 1846 }; 1847 1848 // Cross-Domain tracking 1849 if (options.ga.crossDomainEnabled) { 1850 config.linker = { 1851 accept_incoming: options.ga.crossDomainAcceptIncoming, 1852 domains: options.ga.crossDomainDomains 1853 }; 1854 } 1855 1856 1857 1858 // configure tracking ids 1859 options.ga.trackingIds.forEach(function (trackingId,index) { 1860 config.debug_mode = options.ga.isDebugEnabled.includes("index_" + index); 1861 if(isv4(trackingId)) { 1862 if(options.ga.disableAdvertisingFeatures) { 1863 config.allow_google_signals = false 1864 } 1865 if(options.ga.disableAdvertisingPersonalization) { 1866 config.allow_ad_personalization_signals = false 1867 } 1868 } 1869 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1870 1871 var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category']; 1872 if (options.gdpr['analytics_prior_consent_enabled']) { 1873 if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) { 1874 gtag('config', trackingId, config); 1875 } 1876 } else { 1877 if (Cookiebot.consent[cookiebot_consent_category]) { 1878 gtag('config', trackingId, config); 1879 } 1880 } 1881 1882 } 1883 else 1884 { 1885 gtag('config', trackingId, config); 1886 } 1887 }); 1888 1889 initialized = true; 1890 1891 Utils.fireStaticEvents('ga'); 1892 1893 }, 1894 1895 fireEvent: function (name, data) { 1896 1897 if (!initialized || !this.isEnabled()) { 1898 return false;
1899 } 1900 1901 data.delay = data.delay || 0; 1902 data.params = data.params || {}; 1903 1904 if (data.delay === 0) { 1905 1906 fireEvent(name, data.params); 1907 1908 } else { 1909 1910 setTimeout(function (name, params) { 1911 fireEvent(name, params); 1912 }, data.delay * 1000, name, data.params); 1913 1914 } 1915 1916 return true; 1917 1918 }, 1919 1920 onCommentEvent: function (event) { 1921 this.fireEvent(event.name, event); 1922 }, 1923 1924 onDownloadEvent: function (event) { 1925 this.fireEvent(event.name, event); 1926 }, 1927 1928 onFormEvent: function (event) { 1929 this.fireEvent(event.name, event); 1930 }, 1931 1932 onWooAddToCartOnButtonEvent: function (product_id) { 1933 1934 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1935 return; 1936 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1937 1938 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1939 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 1940 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params) 1941 this.fireEvent(event.name, event); 1942 } 1943 } 1944 1945 1946 }, 1947 1948 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 1949 1950 window.pysWooProductData = window.pysWooProductData || []; 1951 1952 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1953 return; 1954 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1955 1956 if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) { 1957 product_id = parseInt($form.find('input[name="variation_id"]').val()); 1958 } 1959 1960 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1961 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 1962 1963 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params); 1964 if(product_type === Utils.PRODUCT_GROUPED ) { 1965 var groupValue = 0; 1966 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 1967 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 1968 var quantity = parseInt($(this).val()); 1969 if(isNaN(quantity)) { 1970 quantity = 0; 1971 } 1972 var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId]; 1973 // update quantity 1974 event.params.items.forEach(function(el,index,array) { 1975 if(el.id == childItem.content_id) { 1976 if(quantity > 0){ 1977 el.quantity = quantity; 1978 } else { 1979 array.splice(index, 1); 1980 } 1981 } 1982 }); 1983 groupValue += childItem.price * quantity; 1984 }); 1985 if(options.woo.addToCartOnButtonValueEnabled && 1986 options.woo.addToCartOnButtonValueOption !== 'global' && 1987 event.params.hasOwnProperty('ecomm_totalvalue')) { 1988 event.params.ecomm_totalvalue = groupValue; 1989 } 1990 1991 if(groupValue == 0) return;
1991 // skip if no items selected 1992 } else { 1993 // update items qty param 1994 event.params.items[0].quantity = qty; 1995 } 1996 1997 // maybe customize value option 1998 if (options.woo.addToCartOnButtonValueEnabled && 1999 options.woo.addToCartOnButtonValueOption !== 'global' && 2000 product_type !== Utils.PRODUCT_GROUPED) 2001 { 2002 if(event.params.hasOwnProperty('ecomm_totalvalue')) { 2003 event.params.ecomm_totalvalue = event.params.items[0].price * qty; 2004 } 2005 2006 } 2007 2008 2009 this.fireEvent(event.name, event); 2010 } 2011 } 2012 2013 }, 2014 2015 onWooRemoveFromCartEvent: function (event) { 2016 2017 this.fireEvent(event.name, event); 2018 2019 }, 2020 2021 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 2022 2023 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2024 return; 2025 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 2026 2027 2028 if (window.pysEddProductData.hasOwnProperty(download_id)) { 2029 2030 var index; 2031 2032 if (price_index) { 2033 index = download_id + '_' + price_index; 2034 } else { 2035 index = download_id; 2036 } 2037 2038 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 2039 if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) { 2040 2041 Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params); 2042 2043 // update items qty param 2044 event.params.items[0].quantity = qty; 2045 2046 this.fireEvent(event.name,event); 2047 2048 } 2049 } 2050 2051 } 2052 2053 }, 2054 2055 onEddRemoveFromCartEvent: function (event) { 2056 this.fireEvent(event.name, event); 2057 }, 2058 onPageScroll: function (event) { 2059 this.fireEvent(event.name, event); 2060 }, 2061 onTime: function (event) { 2062 this.fireEvent(event.name, event); 2063 }, 2064 2065 }; 2066 2067 }(options); 2068 2069 window.pys = window.pys || {}; 2070 window.pys.Facebook = Facebook; 2071 window.pys.Analytics = Analytics; 2072 window.pys.Utils = Utils; 2073 2074 2075 2076 2077 $(document).ready(function () { 2078 2079 if($("#pys_late_event").length > 0) { 2080 var events = JSON.parse($("#pys_late_event").attr("dir")); 2081 for(var key in events) { 2082 var event = {}; 2083 event[events[key].e_id] = [events[key]]; 2084 if(options.staticEvents.hasOwnProperty(key)) { 2085 Object.assign(options.staticEvents[key], event); 2086 } else { 2087 options.staticEvents[key] = event; 2088 } 2089 2090 } 2091 } 2092 2093 var Pinterest = Utils.setupPinterestObject(); 2094 var Bing = Utils.setupBingObject(); 2095 2096 if((options.woo.enabled || options.edd.enabled) && (options.woo.enabled_save_data_to_orders || options.edd.enabled_save_data_to_orders)) 2097 { 2098 Utils.manageCookies(); 2099 } 2100 else 2101 { 2102 Cookies.remove('pys_first_visit') 2103 Cookies.remove('pysTrafficSource') 2104 Cookies.remove('pys_landing_page') 2105 Cookies.remove('last_pys_landing_page') 2106 Cookies.remove('last_pysTrafficSource') 2107 Cookies.remove('pys_start_session') 2108 Cookies.remove('pys_session_limit') 2109 2110 $.each(Utils.utmTerms, function (index, name) { 2111 Cookies.remove('pys_' + name) 2112 }); 2113 $.each(Utils.utmId,function(index,name) { 2114 Cookies.remove('pys_' + name) 2115 }) 2116 $.each(Utils.utmTerms, function (index, name) { 2117 Cookies.remove('last_pys_' + name) 2118 }); 2119 $.each(Utils.utmId,function(index,name) { 2120 Cookies.remove('last_pys_' + name) 2121 }); 2122 } 2123 Utils.setupGdprCallbacks(); 2124 // page scroll event 2125 if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll") 2126 ) { 2127 2128 var singlePageScroll = function () { 2129 2130 2131 var docHeight = $(document).height() - $(window).height(); 2132 var isFired = false;
2133 2134 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) { 2135 var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll); 2136 for(var i = 0;i<pixels.length;i++) { 2137 var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]); 2138 var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions 2139 2140 if(scroll < $(window).scrollTop()) { 2141 Utils.copyProperties(Utils.getRequestParams(), event.params); 2142 getPixelBySlag(pixels[i]).onPageScroll(event); 2143 isFired = true 2144 } 2145 } 2146 } 2147 if(isFired) { 2148 $(document).off("scroll",singlePageScroll); 2149 } 2150 } 2151 $(document).on("scroll",singlePageScroll); 2152 } 2153 2154 2155 if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) { 2156 var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page); 2157 var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel 2158 setTimeout(function(){ 2159 for(var i = 0;i<pixels.length;i++) { 2160 var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
2161 Utils.copyProperties(Utils.getRequestParams(), event.params); 2162 getPixelBySlag(pixels[i]).onTime(event); 2163 } 2164 },time*1000); 2165 } 2166 2167 // setup Click Event 2168 if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) { 2169 2170 $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) { 2171 2172 var $elem = $(this); 2173 2174 // Download 2175 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") 2176 ) { 2177 var isFired = false; 2178 if ($elem.is('a')) { 2179 var href = $elem.attr('href'); 2180 if (typeof href !== "string") { 2181 return; 2182 } 2183 href = href.trim(); 2184 var extension = Utils.getLinkExtension(href); 2185 var track_download = false; 2186 2187 if (extension.length > 0) { 2188 2189 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) { 2190 var pixels = Object.keys(options.dynamicEvents.automatic_event_download); 2191 for (var i = 0; i < pixels.length; i++) { 2192 var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]); 2193 var extensions = event.extensions; 2194 if (extensions.includes(extension)) { 2195 2196 if(pixels[i] == "tiktok") { 2197 getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event); 2198 } else { 2199 if (options.enable_remove_download_url_param) { 2200 href = href.split('?')[0]; 2201 } 2202 event.params.download_url = href; 2203 event.params.download_type = extension; 2204 event.params.download_name = Utils.getLinkFilename(href); 2205 getPixelBySlag(pixels[i]).onDownloadEvent(event); 2206 } 2207 2208 isFired = true; 2209 } 2210 } 2211 } 2212 } 2213 } 2214 if(isFired) { // prevent duplicate events on the same element 2215 return; 2216 } 2217 } 2218 }); 2219 } 2220 2221 2222 // setup Dynamic events 2223 $.each(options.triggerEventTypes, function (triggerType, events) { 2224 2225 $.each(events, function (eventId, triggers) { 2226 2227 switch (triggerType) { 2228 case 'url_click': 2229 //@see: Utils.setupURLClickEvents() 2230 break; 2231 2232 case 'css_click': 2233 Utils.setupCSSClickEvents(eventId, triggers); 2234 break; 2235 2236 case 'css_mouseover': 2237 Utils.setupMouseOverClickEvents(eventId, triggers); 2238 break; 2239 2240 case 'scroll_pos': 2241 Utils.setupScrollPosEvents(eventId, triggers); 2242 break; 2243 case 'comment': 2244 Utils.setupCommentEvents(eventId, triggers); 2245 break; 2246 } 2247 2248 }); 2249 2250 }); 2251 // setup WooCommerce events 2252 if (options.woo.enabled) { 2253 2254 // WooCommerce AddToCart 2255 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click") 2256 && options.woo.hasOwnProperty("addToCartCatchMethod") 2257 && options.woo.addToCartCatchMethod === "add_cart_js" 2258 ) { 2259 2260 // Loop, any kind of "simple" product, except external 2261 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 2262 2263 var product_id = $(this).data('product_id'); 2264 2265 if (typeof product_id !== 'undefined') { 2266 Facebook.onWooAddToCartOnButtonEvent(product_id); 2267 Analytics.onWooAddToCartOnButtonEvent(product_id); 2268 Pinterest.onWooAddToCartOnButtonEvent(product_id); 2269 Bing.onWooAddToCartOnButtonEvent(product_id); 2270 } 2271 2272 }); 2273 2274 // Single Product 2275 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 2276 // $(document) not work 2277 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 2278 2279 var $button = $(this); 2280 2281 if ($button.hasClass('disabled')) { 2282 return; 2283 } 2284 2285 var $form = $button.closest('form'); 2286 2287 var product_type = Utils.PRODUCT_SIMPLE; 2288 2289 if ($form.length === 0) { 2290 return ; 2291 } else if ($form.hasClass('variations_form')) { 2292 product_type = Utils.PRODUCT_VARIABLE; 2293 } else if($form.hasClass('bundle_form')) { 2294 product_type = Utils.PRODUCT_BUNDLE; 2295 } else if($form.hasClass('grouped_form')) { 2296 product_type = Utils.PRODUCT_GROUPED; 2297 } 2298 2299 2300 2301 2302 var product_id; 2303 var qty; 2304 2305 if (product_type === Utils.PRODUCT_GROUPED) { 2306 qty = 1; 2307 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 2308 } else if (product_type === Utils.PRODUCT_VARIABLE) { 2309 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 2310 var qtyTag = $form.find('input[name="quantity"]'); 2311 if(qtyTag.length <= 0) { 2312 qtyTag = $form.find('select[name="quantity"]'); 2313 } 2314 qty = parseInt(qtyTag.val()); 2315 } else { 2316 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 2317 var qtyTag = $form.find('input[name="quantity"]'); 2318 if(qtyTag.length <= 0) { 2319 qtyTag = $form.find('select[name="quantity"]'); 2320 } 2321 qty = parseInt(qtyTag.val()); 2322 } 2323 2324 Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 2325 Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 2326 2327 Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 2328 Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 2329 2330 }); 2331 2332 } 2333 2334 // WooCommerce RemoveFromCart 2335 if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) { 2336 2337 $('body').on('click', options.woo.removeFromCartSelector, function (e) { 2338 2339 var $a = $(e.currentTarget), 2340 href = $a.attr('href'); 2341 2342 // extract cart item hash from remove button URL 2343 var regex = new RegExp("[\\?&]remove_item=([^&#]*)"), 2344 results = regex.exec(href); 2345 2346 if (results !== null) { 2347 2348 var item_hash = results[1]; 2349 2350 if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) { 2351 var events = options.dynamicEvents["woo_remove_from_cart"][item_hash]; 2352 Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events) 2353 } 2354 2355 } 2356 2357 }); 2358 } 2359 } 2360 2361 // setup EDD events 2362 if (options.edd.enabled) { 2363 2364 // EDD AddToCart 2365 if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) { 2366 2367 $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) { 2368 2369 var $button = $(this); 2370 var $form = $button.closest('form'); 2371 var variable_price = $button.data('variablePrice'); // yes/no 2372 var price_mode = $button.data('priceMode'); // single/multi 2373 var ids = []; 2374 var quantities = []; 2375 var qty; 2376 var id; 2377 2378 if (variable_price === 'yes' && price_mode === 'multi') { 2379 2380 id = $form.find('input[name="download_id"]').val(); 2381 2382 // get selected variants 2383 $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) { 2384 ids.push(id + '_' + $(el).val()); 2385 }); 2386 2387 // get qty for selected variants 2388 $.each(ids, function (i, variant_id) { 2389 2390 var variant_index = variant_id.split('_', 2); 2391 qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val(); 2392 2393 if (typeof qty !== 'undefined') { 2394 quantities.push(qty); 2395 } else { 2396 quantities.push(1); 2397 } 2398 2399 }); 2400 2401 } else if (variable_price === 'yes' && price_mode === 'single') { 2402 2403 id = $form.find('input[name="download_id"]').val(); 2404 ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val()); 2405 2406 qty = $form.find('input[name="edd_download_quantity"]').val(); 2407 2408 if (typeof qty !== 'undefined') { 2409 quantities.push(qty); 2410 } else { 2411 quantities.push(1); 2412 } 2413 2414 } else { 2415 2416 ids.push($button.data('downloadId')); 2417 2418 qty = $form.find('input[name="edd_download_quantity"]').val(); 2419 2420 if (typeof qty !== 'undefined') { 2421 quantities.push(qty); 2422 } else { 2423 quantities.push(1); 2424 } 2425 } 2426 2427 // fire event for each download/variant 2428 $.each(ids, function (i, download_id) { 2429 2430 var q = parseInt(quantities[i]); 2431 var variant_index = download_id.toString().split('_', 2); 2432 var price_index; 2433 2434 if (variant_index.length === 2) { 2435 download_id = variant_index[0]; 2436 price_index = variant_index[1]; 2437 } 2438 2439 Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2440 Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2441 Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2442 Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2443 2444 }); 2445 2446 }); 2447 2448 } 2449 2450 2451 // EDD RemoveFromCart 2452 if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) { 2453 2454 $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) { 2455 2456 var href = $(this).attr('href'); 2457 if(href) { 2458 var key = href.substring(href.indexOf('=') + 1).charAt(0); 2459 if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) { 2460 var events = options.dynamicEvents.edd_remove_from_cart[key]; 2461 Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events) 2462 } 2463 } 2464 }); 2465 2466 } 2467 2468 } 2469 2470 // setup Comment Event 2471 if (options.dynamicEvents.hasOwnProperty("automatic_event_c
2471omment") 2472 ) { 2473 2474 $('form.comment-form').on("submit",function () { 2475 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) { 2476 var pixels = Object.keys(options.dynamicEvents.automatic_event_comment); 2477 for (var i = 0; i < pixels.length; i++) { 2478 var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]); 2479 Utils.copyProperties(Utils.getRequestParams(), event.params); 2480 getPixelBySlag(pixels[i]).onCommentEvent(event); 2481 } 2482 } 2483 }); 2484 2485 } 2486 2487 2488 // setup Form Event 2489 if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 2490 2491 $(document).onFirst('submit', 'form', function (e) { 2492 2493 var $form = $(this); 2494 2495 // exclude WP forms 2496 if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') { 2497 return; 2498 } 2499 2500 // exclude Woo forms 2501 if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') || 2502 $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) { 2503 return; 2504 } 2505 2506 // exclude EDD forms 2507 if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) { 2508 return; 2509 } 2510// exclude CF7 forms 2511 if ($form.hasClass('wpcf7-form')) { 2512 return; 2513 } 2514 // exclude Forminator forms 2515 if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) { 2516 return; 2517 } 2518 // exclude WPforms forms 2519 if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) { 2520 return; 2521 } 2522 // exclude Formidable forms 2523 /*if ($form.hasClass('frm-show-form')) { 2524 return; 2525 }*/ 2526 // exclude Ninja Forms forms 2527 if ($form.parent().hasClass('nf-form-layout')) { 2528 return; 2529 } 2530 // exclude Fluent forms 2531 if ($form.hasClass('frm-fluent-form')) { 2532 return; 2533 } 2534 if(!options.enable_success_send_form) { 2535 var params = { 2536 form_id: $form.attr('id'), 2537 form_class: $form.attr('class'), 2538 text: $form.find('[type="submit"]').is('input') ? 2539 $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text() 2540 }; 2541 2542 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 2543 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 2544 for (var i = 0; i < pixels.length; i++) { 2545 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 2546 2547 if (pixels[i] === "tiktok") { 2548 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 2549 } else { 2550 Utils.copyProperties(params, event.params,) 2551 Utils.copyProperties(Utils.getRequestParam
2551s(), event.params); 2552 getPixelBySlag(pixels[i]).onFormEvent(event); 2553 } 2554 } 2555 } 2556 } 2557 }); 2558 2559 document.addEventListener( 'wpcf7mailsent', function( event ) { 2560 var form_id = event.detail.contactFormId; 2561 sendFormAction($(event.target), form_id); 2562 }, false ); 2563 //Forminator 2564 $(document).on( 'forminator:form:submit:success', function( event ){ 2565 var form_id = $(event.target).find('input[name="form_id"]').val(); 2566 sendFormAction($(event.target), form_id); 2567 }); 2568 2569 //WPForm 2570 $('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => { 2571 var form_id = $(event.target).attr('data-formid'); 2572 sendFormAction($(event.target), form_id); 2573 }) 2574 $(document).on( 'frmFormComplete', function( event, form, response ) { 2575 const form_id = $(form).find('input[name="form_id"]').val(); 2576 sendFormAction($(event.target), form_id); 2577 }); 2578 // Ninja Forms 2579 $(document).onFirst('nfFormSubmitResponse', function (event, data) { 2580 const form_id = data.response.data.form_id; 2581 sendFormAction($(event.target), form_id); 2582 }); 2583 2584 var fluentForms = $('form.frm-fluent-form'); 2585 fluentForms.each(function() { 2586 var $form = $(this); 2587 $form.on('fluentform_submission_success', function(event) { 2588 var $formItem = $(this); 2589 var form_id = $formItem.attr('data-form_id'); 2590 sendFormAction($(event.target), form_id); 2591 }); 2592 }); 2593 2594 } 2595 2596 2597 // load pixel APIs 2598 Utils.loadPixels(); 2599 // setup Enrich content 2600 if(Utils.isCheckoutPage()) { 2601 Utils.addCheckoutFields(); 2602 } 2603 }); 2604 2605 var sendFormAction = function (form_target, formId){ 2606 var params = { 2607 form_id: formId, 2608 text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() : 2609 form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() : 2610 form_target.find('[type="submit"]').text() 2611 }; 2612 2613 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 2614 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 2615 for (var i = 0; i < pixels.length; i++) { 2616 var event = options.dynamicEvents.automatic_event_form[pixels[i]]; 2617 if (pixels[i] === "tiktok") { 2618 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 2619 } else { 2620 Utils.copyProperties(params, event.params)
2621 Utils.copyProperties(Utils.getRequestParams(), event.params); 2622 getPixelBySlag(pixels[i]).onFormEvent(event); 2623 } 2624 } 2625 } 2626 } 2627 2628}(jQuery, pysOptions); 2629 2630function pys_generate_token(length){ 2631 //edit the token allowed characters 2632 var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split(""); 2633 var b = []; 2634 for (var i=0; i<length; i++) { 2635 var j = (Math.random() * (a.length-1)).toFixed(0); 2636 b[i] = a[j]; 2637 } 2638 return b.join(""); 2639} 2640 2641function getBundlePriceOnSingleProduct(data) { 2642 var items_sum = 0; 2643 jQuery(".bundle_form .bundled_product").each(function(index){ 2644 var id = jQuery(this).find(".cart").data("bundled_item_id"); 2645 var item_price = data.prices[id]; 2646 var item_quantity = jQuery(this).find(".bundled_qty").val(); 2647 if(!jQuery(this).hasClass("bundled_item_optional") || 2648 jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) { 2649 items_sum += item_price*item_quantity; 2650 } 2651 }); 2652 return items_sum; 2653} 2654 2655function getPixelBySlag(slug) { 2656 switch (slug) { 2657 case "facebook": return window.pys.Facebook; 2658 case "ga": return window.pys.Analytics; 2659 case "bing": return window.pys.Bing; 2660 case "pinterest": return window.pys.Pinterest; 2661 } 2662} 2663var getUrlParameter = function getUrlParameter(sParam) { 2664 var sPageURL = window.location.search.substring(1), 2665 sURLVariables = sPageURL.split('&'), 2666 sParameterName, 2667 i; 2668 2669 for (i = 0; i < sURLVariables.length; i++) { 2670 sParameterName = sURLVariables[i].split('='); 2671 2672 if (sParameterName[0] === sParam) { 2673 return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 2674 } 2675 } 2676 return false; 2677};
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.