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 function loadPixels() { 192 193 if (!options.gdpr.all_disabled_by_api) { 194 195 if (!options.gdpr.facebook_disabled_by_api) { 196 Facebook.loadPixel(); 197 } 198 199 if (!options.gdpr.analytics_disabled_by_api) { 200 Analytics.loadPixel(); 201 } 202 203 if (!options.gdpr.pinterest_disabled_by_api) { 204 Pinterest.loadPixel(); 205 } 206 207 if (!options.gdpr.bing_disabled_by_api) { 208 Bing.loadPixel(); 209 } 210 } 211 212 } 213 214 /** 215 * PUBLIC API 216 */ 217 return { 218 PRODUCT_SIMPLE : 0, 219 PRODUCT_VARIABLE : 1, 220 PRODUCT_BUNDLE : 2, 221 PRODUCT_GROUPED : 3, 222 fireEventForAllPixel:function(functionName,events){ 223 if (events.hasOwnProperty(Facebook.tag())) 224 Facebook[functionName](events[Facebook.tag()]); 225 if (events.hasOwnProperty(Analytics.tag())) 226 Analytics[functionName](events[Analytics.tag()]); 227 if (events.hasOwnProperty(Pinterest.tag())) 228 Pinterest[functionName](events[Pinterest.tag()]); 229 if (events.hasOwnProperty(Bing.tag())) 230 Bing[functionName](events[Bing.tag()]); 231 }, 232 233 setupPinterestObject: function () { 234 Pinterest = window.pys.Pinterest || Pinterest; 235 return Pinterest; 236 }, 237 238 setupBingObject: function () { 239 Bing = window.pys.Bing || Bing; 240 return Bing; 241 }, 242 243 // Clone all object members to another and return it 244 copyProperties: function (from, to) { 245 for (var key in from) { 246 if("function" == typeof from[key]) { 247 continue; 248 } 249 to[key] = from[key]; 250 } 251 return to; 252 }, 253 // clone object 254 clone: function(obj) { 255 var copy; 256 257 // Handle the 3 simple types, and null or undefined 258 if (null == obj || "object" != typeof obj) return obj; 259 260 // Handle Date 261 if (obj instanceof Date) { 262 copy = new Date(); 263 copy.setTime(obj.getTime()); 264 return copy; 265 } 266 267 // Handle Array 268 if (obj instanceof Array) { 269 copy = []; 270 for (var i = 0, len = obj.length; i < len; i++) { 271 if("function" == typeof obj[i]) { 272 continue; 273 } 274 copy[i] = Utils.clone(obj[i]); 275 } 276 return copy; 277 } 278 279 // Handle Object 280 if (obj instanceof Object) { 281 copy = {}; 282 for (var attr in obj) { 283 if (obj.hasOwnProperty(attr)) { 284 if("function" == typeof obj[attr]) { 285 continue; 286 } 287 copy[attr] = Utils.clone(obj[attr]); 288 } 289 } 290 return copy; 291 } 292 293 return obj; 294 }, 295 296 // Returns array of elements with given tag name 297 getTagsAsArray: function (tag) { 298 return [].slice.call(document.getElementsByTagName(tag)); 299 }, 300
301 getRequestParams: function () { 302 return []; 303 }, 304 305 /** 306 * CUSTOM EVENTS 307 */ 308 309 setupMouseOverClickEvents: function (eventId, triggers) { 310 311 // Non-default binding used to avoid situations when some code in external js 312 // stopping events propagation, eg. returns false, and our handler will never called 313 $(document).onFirst('mouseover', triggers.join(','), function () { 314 315 // do not fire event multiple times 316 if ($(this).hasClass('pys-mouse-over-' + eventId)) { 317 return true; 318 } else { 319 $(this).addClass('pys-mouse-over-' + eventId); 320 } 321 322 Utils.fireDynamicEvent(eventId); 323 324 }); 325 326 }, 327 328 setupCSSClickEvents: function (eventId, triggers) { 329 330 // Non-default binding used to avoid situations when some code in external js 331 // stopping events propagation, eg. returns false, and our handler will never called 332 $(document).onFirst('click', triggers.join(','), function () { 333 Utils.fireTriggerEvent(eventId); 334 }); 335 }, 336 337 setupURLClickEvents: function () { 338 339 // Non-default binding used to avoid situations when some code in external js 340 // stopping events propagation, eg. returns false, and our handler will never called 341 $('a[data-pys-event-id]').onFirst('click', function (evt) { 342 343 $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) { 344 345 eventId = parseInt(eventId); 346 347 if (isNaN(eventId) === false) { 348 Utils.fireTriggerEvent(eventId); 349 } 350 351 }); 352 353 }); 354 355 356 }, 357 358 setupScrollPosEvents: function (eventId, triggers) { 359 360 var scrollPosThresholds = {}, 361 docHeight = $(document).height() - $(window).height(); 362 363 // convert % to absolute positions 364 $.each(triggers, function (index, scrollPos) { 365 366 // convert % to pixels 367 scrollPos = docHeight * scrollPos / 100; 368 scrollPos = Math.round(scrollPos); 369 370 scrollPosThresholds[scrollPos] = eventId; 371 372 }); 373 374 $(document).on("scroll",function () { 375 376 var scrollPos = $(window).scrollTop(); 377 378 $.each(scrollPosThresholds, function (threshold, eventId) { 379 380 // position has not reached yes 381 if (scrollPos <= threshold) { 382 return true; 383 } 384 385 // fire event only once 386 if (eventId === null) { 387 return true; 388 } else { 389 scrollPosThresholds[threshold] = null; 390 } 391 392 Utils.fireTriggerEvent(eventId); 393 394 }); 395 396 }); 397 398 399 }, 400 setupCommentEvents : function (eventId,triggers) { 401 $('form.comment-form').on("submit",function () { 402 Utils.fireTriggerEvent(eventId); 403 }); 404 }, 405 406 /** 407 * Events 408 */ 409 410 fireTriggerEvent: function (eventId) { 411 412 if (!options.triggerEvents.hasOwnProperty(eventId)) { 413 return; 414 } 415 416 var event = {}; 417 var events = options.triggerEvents[eventId]; 418 419 if (events.hasOwnProperty('facebook')) { 420 event = events.facebook; 421 Facebook.fireEvent(event.name, event); 422 } 423 424 if (events.hasOwnProperty('ga')) { 425 event = events.ga; 426 Analytics.fireEvent(event.name, event); 427 } 428 429 if (events.hasOwnProperty('pinterest')) { 430 event = events.pinterest; 431 Pinterest.fireEvent(event.name, event); 432 } 433 434 if (events.hasOwnProperty('bing')) { 435 event = events.bing; 436 Bing.fireEvent(event.name, event); 437 } 438 }, 439 440 fireStaticEvents: function (pixel) { 441 442 if (options.staticEvents.hasOwnProperty(pixel)) { 443 444 $.each(options.staticEvents[pixel], function (eventName, events) { 445 $.each(events, function (index, eventData) { 446 447 eventData.fired = eventData.fired || false; 448 449 if (!eventData.fired) { 450 451 var fired = false;
452 453 // fire event 454 if ('facebook' === pixel) { 455 fired = Facebook.fireEvent(eventData.name, eventData); 456 } else if ('ga' === pixel) { 457 fired = Analytics.fireEvent(eventData.name, eventData); 458 } else if ('pinterest' === pixel) { 459 fired = Pinterest.fireEvent(eventData.name, eventData); 460 } else if ('bing' === pixel) { 461 fired = Bing.fireEvent(eventData.name, eventData); 462 } 463 464 // prevent event double event firing 465 eventData.fired = fired; 466 467 } 468 469 }); 470 }); 471 472 } 473 474 }, 475 476 /** 477 * Load tag's JS 478 * 479 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/ 480 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 481 */ 482 loadGoogleTag: function (id) { 483 484 if (!gtag_loaded) { 485 486 (function (window, document, src) { 487 var a = document.createElement('script'), 488 m = document.getElementsByTagName('script')[0]; 489 a.async = 1; 490 a.src = src; 491 m.parentNode.insertBefore(a, m); 492 })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id); 493 494 window.dataLayer = window.dataLayer || []; 495 window.gtag = window.gtag || function gtag() { 496 dataLayer.push(arguments); 497 }; 498 499 gtag('js', new Date()); 500 501 gtag_loaded = true; 502 503 } 504 505 }, 506 507 /** 508 * GDPR 509 */ 510 511 loadPixels: function () { 512 513 if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) { 514 515 // retrieves actual PYS GDPR filters values which allow to avoid cache issues 516 $.get({ 517 url: options.ajaxUrl, 518 dataType: 'json', 519 data: { 520 action: 'pys_get_gdpr_filters_values' 521 }, 522 success: function (res) { 523 524 if (res.success) { 525 526 options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api; 527 options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api; 528 options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api; 529 options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api; 530 options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api; 531 options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api; 532 533 } 534 535 loadPixels(); 536 537 } 538 }); 539 540 } else { 541 loadPixels(); 542 } 543 544 }, 545 546 consentGiven: function (pixel) { 547 548 /** 549 * ConsentMagic 550 */ 551 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 552 553 var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix); 554 555 if (options.gdpr[pixel + '_prior_consent_enabled']) { 556 if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') { 557 return true; 558 } 559 } else { 560 if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') { 561 return true; 562 } 563 } 564 565 return false;
566 567 } 568 569 /** 570 * Real Cookie Banner 571 */ 572 if(options.gdpr.real_cookie_banner_integration_enabled) { 573 var consentApi = window.consentApi; 574 if (consentApi) { 575 switch (pixel) { 576 case "analytics": 577 return consentApi.consentSync("http", "_ga", "*").cookieOptIn; 578 case "facebook": 579 return consentApi.consentSync("http", "_fbp", "*").cookieOptIn; 580 case "pinterest": 581 return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn; 582 default: 583 return true; 584 } 585 } 586 } 587 588 /** 589 * Cookiebot 590 */ 591 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 592 593 var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category']; 594 595 if (options.gdpr[pixel + '_prior_consent_enabled']) { 596 if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) { 597 return true; 598 } 599 } else { 600 if (Cookiebot.consent[cookiebot_consent_category]) { 601 return true; 602 } 603 } 604 605 return false; 606 607 } 608 609 /** 610 * Cookie Notice 611 */ 612 if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') { 613 614 var cn_cookie = Cookies.get(cnArgs.cookieName); 615 616 if (options.gdpr[pixel + '_prior_consent_enabled']) { 617 if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') { 618 return true; 619 } 620 } else { 621 if (cn_cookie === 'true') { 622 return true; 623 } 624 } 625 626 return false; 627 628 } 629 630 /** 631 * Cookie Law Info 632 */ 633 if (options.gdpr.cookie_law_info_integration_enabled) { 634 635 var cli_cookie = Cookies.get('viewed_cookie_policy'); 636 637 if (options.gdpr[pixel + '_prior_consent_enabled']) { 638 if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') { 639 return true; 640 } 641 } else { 642 if (cli_cookie === 'yes') { 643 return true; 644 } 645 } 646 647 return false; 648 649 } 650 651 return true; 652 653 }, 654 655 setupGdprCallbacks: function () { 656 /** 657 * ConsentMagic 658 */ 659 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 660 var test_prefix = CS_Data.test_prefix, 661 cs_refresh_after_consent = false, 662 substring = "cs_enabled_cookie_term"; 663 664 if (CS_Data.cs_refresh_after_consent == 1) { 665 cs_refresh_after_consent = CS_Data.cs_refresh_after_consent; 666 } 667 668 if (!cs_refresh_after_consent) { 669 var theCookies = document.cookie.split(';'); 670 for (var i = 1 ; i <= theCookies.length; i++) { 671 if (theCookies[i-1].indexOf(substring) !== -1) { 672 var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_',''); 673 categoryCookie = Number(categoryCookie.replace(/\D+/g,"")); 674 var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie); 675 if(cs_cookie_val == 'yes') { 676 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 677 Facebook.loadPixel(); 678 } 679 680 if (categoryCookie === CS_Data.cs_script_cat.bing) { 681 Bing.loadPixel(); 682 } 683 684 if (categoryCookie === CS_Data.cs_script_cat.analytics) { 685 Analytics.loadPixel(); 686 } 687 688 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 689 Pinterest.loadPixel(); 690 } 691 } else { 692 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 693 Facebook.disable(); 694 } 695 696 if (categoryCookie === CS_Data.cs_script_cat.bing) { 697 Bing.disable(); 698 } 699 700 if (categoryCookie === CS_Data.cs_script_cat.analytics) { 701 Analytics.disable(); 702 } 703 704 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 705 Pinterest.disable(); 706 } 707 } 708 if (Cookies.get('cs_enabled_advanced_matching') == 'yes') { 709 Facebook.loadPixel(); 710 } 711 } 712 } 713 714 $(document).on('click','.cs_action_btn',function(e) { 715 e.preventDefault(); 716 var elm = $(this), 717 button_action = elm.attr('data-cs_action'); 718 719 if(button_action === 'allow_all') { 720 Facebook.loadPixel(); 721 Bing.loadPixel(); 722 Analytics.loadPixel(); 723 Pinterest.loadPixel(); 724 } else if(button_action === 'disable_all') { 725 Facebook.disable(); 726 Bing.disable(); 727 Analytics.disable(); 728 Pinterest.disable(); 729 } 730 }); 731 } 732 } 733 /** 734 * Real Cookie Banner 735 */ 736 if(options.gdpr.real_cookie_banner_integration_enabled) { 737 var consentApi = window.consentApi; 738 if (consentApi) { 739 consentApi.consent("http", "_ga", "*") 740 .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics)); 741 consentApi.consent("http", "_fbp", "*") 742 .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook)); 743 consentApi.consent("http", "_pinterest_sess", ".pinterest.com") 744 .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest)); 745 } 746 } 747 /** 748 * Cookiebot 749 */ 750 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 751 752 window.addEventListener("CookiebotOnConsentReady", function() { 753 if (Cookiebot.consent.marketing) { 754 Facebook.loadPixel(); 755 Bing.loadPixel(); 756 Pinterest.loadPixel(); 757 758 } 759 if (Cookiebot.consent.statistics) { 760 Analytics.loadPixel(); 761 } 762 if (!Cookiebot.consent.marketing) { 763 Facebook.disable(); 764 Pinterest.disable(); 765 Bing.disable() 766 } 767 if (!Cookiebot.consent.statistics) { 768 Analytics.disable(); 769 } 770 }); 771 772 } 773 774 /** 775 * Cookie Notice 776 */ 777 if (options.gdpr.cookie_notice_integration_enabled) { 778 779 $(document).onFirst('click', '.cn-set-cookie', function () { 780 781 if ($(this).data('cookie-set') === 'accept') { 782 Facebook.loadPixel(); 783 Analytics.loadPixel(); 784 Pinterest.loadPixel(); 785 Bing.loadPixel(); 786 } else { 787 Facebook.disable(); 788 Analytics.disable(); 789 Pinterest.disable(); 790 Bing.disable(); 791 } 792 793 }); 794 795 $(document).onFirst('click', '.cn-revoke-cookie', function () { 796 Facebook.disable(); 797 Analytics.disable(); 798 Pinterest.disable(); 799 Bing.disable(); 800 }); 801 802 } 803 804 /** 805 * Cookie Law Info 806 */ 807 if (options.gdpr.cookie_law_info_integration_enabled) { 808 809 $(document).onFirst('click', '#cookie_action_close_header', function () { 810 Facebook.loadPixel(); 811 Analytics.loadPixel(); 812 Pinterest.loadPixel(); 813 Bing.loadPixel(); 814 }); 815 816 $(document).onFirst('click', '#cookie_action_close_header_reject', function () { 817 Facebook.disable(); 818 Analytics.disable(); 819 Pinterest.disable(); 820 Bing.disable(); 821 }); 822 823 } 824 825 }, 826 827 /** 828 * DOWNLOAD DOCS 829 */ 830 831 getLinkExtension: function (link) { 832 833 // Remove anchor, query string and everything before last slash 834 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 835 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 836 link = link.substring(link.lastIndexOf("/") + 1, link.length); 837 838 // If there's a period left in the URL, then there's a extension 839 if (link.length > 0 && link.indexOf('.') !== -1) { 840 link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period 841 return link; 842 } else { 843 return ""; 844 } 845 }, 846 847 getLinkFilename: function (link) { 848 849 // Remove anchor, query string and everything before last slash 850 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 851 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 852 link = link.substring(link.lastIndexOf("/") + 1, link.length); 853 854 // If there's a period left in the URL, then there's a extension 855 if (link.length > 0 && link.indexOf('.') !== -1) { 856 return link; 857 } else { 858 return ""; 859 } 860 } 861 862 }; 863 864 }(options); 865 866 var Facebook = function (options) { 867 868 869 var defaultEventTypes = [ 870 'PageView', 871 'ViewContent', 872 'Search', 873 'AddToCart', 874 'AddToWishlist', 875 'InitiateCheckout', 876 'AddPaymentInfo', 877 'Purchase', 878 'Lead', 879 880 'Subscribe', 881 'CustomizeProduct', 882 'FindLocation', 883 'StartTrial', 884 'SubmitApplication', 885 'Schedule', 886 'Contact', 887 'Donate' 888 ]; 889 890 var initialized = false;
891 892 // fire server side event gdpr plugin installed 893 var isApiDisabled = options.gdpr.all_disabled_by_api || 894 options.gdpr.facebook_disabled_by_api || 895 options.gdpr.cookiebot_integration_enabled || 896 options.gdpr.consent_magic_integration_enabled || 897 options.gdpr.cookie_notice_integration_enabled || 898 options.gdpr.cookie_law_info_integration_enabled; 899 900 function fireEvent(name, allData) { 901 902 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) { 903 return; 904 } 905 906 var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom'; 907 var data = allData.params; 908 var params = {}; 909 var arg = {}; 910 Utils.copyProperties(data, params); 911 912 if(options.facebook.serverApiEnabled) { 913 914 var isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod") 915 && options.woo.addToCartCatchMethod === "add_cart_js"; 916 917 if(allData.e_id === "woo_remove_from_cart" 918 || (isAddToCartFromJs && allData.e_id === "woo_add_to_cart_on_button_click")) 919 { 920 Facebook.updateEventId(allData.name); 921 allData.eventID = Facebook.getEventId(allData.name); 922 } else if( options.facebook.ajaxForServerEvent 923 || isApiDisabled 924 || allData.delay > 0 925 || allData.type !== "static") 926 { // send event from server if they was bloc by gdpr or need send with delay 927 allData.eventID = pys_generate_token(36); 928 var json = { 929 action: 'pys_api_event', 930 pixel: 'facebook', 931 event: name, 932 data:data, 933 ids:options.facebook.pixelIds, 934 eventID:allData.eventID, 935 url:window.location.href, 936 }; 937 if(allData.hasOwnProperty('woo_order')) { 938 json['woo_order'] = allData.woo_order; 939 } 940 if(allData.hasOwnProperty('edd_order')) { 941 json['edd_order'] = allData.edd_order; 942 } 943 944 if(allData.delay > 0) { 945 jQuery.ajax( { 946 type: 'POST', 947 url: options.ajaxUrl, 948 data: json, 949 headers: { 950 'Cache-Control': 'no-cache' 951 }, 952 success: function(){}, 953 }); 954 } else { 955 // if(name != "AddToCart") { // AddToCart call from hook 956 setTimeout(function (json) { 957 jQuery.ajax({ 958 type: 'POST', 959 url: options.ajaxUrl, 960 data: json, 961 headers: { 962 'Cache-Control': 'no-cache' 963 }, 964 success: function () { 965 }, 966 }); 967 }, 500, json); 968 //} 969 } 970 } 971 } 972 973 974 if("hCR" === name) { 975 return; 976 } 977 978 if (options.debug) { 979 console.log('[Facebook] ' + name, params,"eventID",allData.eventID); 980 } 981 982 if(allData.hasOwnProperty('eventID')) { 983 arg.eventID = allData.eventID; 984 } 985 986 fbq(actionType, name, params,arg); 987 } 988 989 /** 990 * Public API 991 */ 992 return { 993 tag: function() { 994 return "facebook"; 995 }, 996 isEnabled: function () { 997 return options.hasOwnProperty('facebook'); 998 }, 999 1000 disable: function () { 1001 initialized = false;
1002 }, 1003 1004 /** 1005 * Load pixel's JS 1006 */ 1007 loadPixel: function () { 1008 1009 if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) { 1010 return; 1011 } 1012 1013 !function (f, b, e, v, n, t, s) { 1014 if (f.fbq) return; 1015 n = f.fbq = function () { 1016 n.callMethod ? 1017 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 1018 }; 1019 if (!f._fbq) f._fbq = n; 1020 n.push = n; 1021 n.loaded = !0; 1022 n.version = '2.0'; 1023 n.agent = 'dvpixelyoursite'; 1024 n.queue = []; 1025 t = b.createElement(e); 1026 t.async = !0; 1027 t.src = v; 1028 s = b.getElementsByTagName(e)[0]; 1029 s.parentNode.insertBefore(t, s) 1030 }(window, 1031 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 1032 1033 // initialize pixel 1034 options.facebook.pixelIds.forEach(function (pixelId) { 1035 1036 if (options.facebook.removeMetadata) { 1037 fbq('set', 'autoConfig', false, pixelId); 1038 } 1039 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 1040 if(options.facebook.advancedMatching.length === 0) { 1041 fbq('init', pixelId); 1042 } else { 1043 var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix); 1044 if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) { 1045 if (cs_advanced_matching == 'yes') { 1046 fbq('init', pixelId, options.facebook.advancedMatching); 1047 } else { 1048 fbq('init', pixelId); 1049 } 1050 } else { 1051 fbq('init', pixelId, options.facebook.advancedMatching); 1052 } 1053 } 1054 } else { 1055 if (options.facebook.advancedMatching.length === 0) { 1056 fbq('init', pixelId); 1057 } else { 1058 fbq('init', pixelId, options.facebook.advancedMatching); 1059 } 1060 } 1061 }); 1062 1063 initialized = true; 1064 1065 Utils.fireStaticEvents('facebook'); 1066 1067 }, 1068 1069 fireEvent: function (name, data) { 1070 1071 if (!initialized || !this.isEnabled()) { 1072 return false; 1073 } 1074 1075 data.delay = data.delay || 0; 1076 data.params = data.params || {}; 1077 1078 if (data.delay === 0) { 1079 1080 fireEvent(name, data); 1081 1082 } else { 1083 1084 setTimeout(function (name, params) { 1085 fireEvent(name, params); 1086 }, data.delay * 1000, name, data); 1087 1088 } 1089 1090 return true; 1091 1092 }, 1093 1094 onCommentEvent: function (event) { 1095 this.fireEvent(event.name, event); 1096 }, 1097 1098 onDownloadEvent: function (event) { 1099 this.fireEvent(event.name, event); 1100 }, 1101 1102 onFormEvent: function (event) { 1103 1104 this.fireEvent(event.name, event); 1105 1106 }, 1107 1108 onWooAddToCartOnButtonEvent: function (product_id) { 1109 1110 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1111 return; 1112 var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]; 1113 1114 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1115 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 1116 event = Utils.copyProperties(event, {}) 1117 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params) 1118 this.fireEvent(event.name, event); 1119 } 1120 } 1121 }, 1122 1123 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 1124 1125 window.pysWooProductData = window.pysWooProductData || []; 1126 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1127 return; 1128 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1129 1130 if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) { 1131 product_id = parseInt($form.find('input[name="variation_id"]').val()); 1132 } 1133 1134 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1135 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 1136 1137 1138 Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params); 1139 1140 var groupValue = 0; 1141 if(product_type === Utils.PRODUCT_GROUPED ) { 1142 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 1143 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 1144 var quantity = parseInt($(this).val()); 1145 if(isNaN(quantity)) { 1146 quantity = 0; 1147 } 1148 var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId]; 1149 1150 if(quantity == 0) { 1151 event.params.content_ids.forEach(function(el,index,array) { 1152 if(el == childItem.content_id) { 1153 array.splice(index, 1); 1154 } 1155 }); 1156 } 1157 1158 if(event.params.hasOwnProperty('contents')) { 1159 event.params.contents.forEac
1159h(function(el,index,array) { 1160 if(el.id == childItem.content_id) { 1161 if(quantity > 0){ 1162 el.quantity = quantity; 1163 } else { 1164 array.splice(index, 1); 1165 } 1166 } 1167 }); 1168 } 1169 1170 1171 groupValue += childItem.price * quantity; 1172 }); 1173 if(groupValue == 0) return; // skip if no items selected 1174 } 1175 1176 // maybe customize value option 1177 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 1178 1179 if(product_type === Utils.PRODUCT_GROUPED) { 1180 event.params.value = groupValue; 1181 } else if(product_type === Utils.PRODUCT_BUNDLE) { 1182 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 1183 var items_sum = getBundlePriceOnSingleProduct(data); 1184 event.params.value = (parseInt(data.base_price) + items_sum )* qty; 1185 } else { 1186 event.params.value = event.params.value * qty; 1187 } 1188 } 1189 1190 // only when non Facebook for WooCommerce logic used 1191 if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) { 1192 event.params.contents[0].quantity = qty; 1193 } 1194 1195 this.fireEvent(event.name, event); 1196 1197 } 1198 } 1199 }, 1200 1201 onWooRemoveFromCartEvent: function (event) { 1202 this.fireEvent(event.name, event); 1203 }, 1204 1205 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 1206 1207 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1208 return; 1209 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 1210 1211 if (window.pysEddProductData.hasOwnProperty(download_id)) { 1212 1213 var index; 1214 1215 if (price_index) { 1216 index = download_id + '_' + price_index; 1217 } else { 1218 index = download_id; 1219 } 1220 1221 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 1222 if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) { 1223 1224 1225 Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params) 1226 1227 // maybe customize value option 1228 if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') { 1229 event.params.value = event.params.value * qty; 1230 } 1231 1232 // update contents qty param 1233 var contents = event.params.contents; 1234 contents[0].quantity = qty; 1235 event.params.contents = contents; 1236 1237 this.fireEvent(event.name,event); 1238 1239 } 1240 } 1241 1242 } 1243 1244 }, 1245 1246 onEddRemoveFromCartEvent: function (event) { 1247 this.fireEvent(event.name, event); 1248 }, 1249 onPageScroll: function (event) { 1250 this.fireEvent(event.name, event); 1251 }, 1252 onTime: function (event) { 1253 this.fireEvent(event.name, event); 1254 },
1255 initEventIdCookies: function (key) { 1256 var ids = {}; 1257 ids[key] = pys_generate_token(36) 1258 Cookies.set('pys_fb_event_id', JSON.stringify(ids)); 1259 }, 1260 updateEventId:function(key) { 1261 var cooData = Cookies.get("pys_fb_event_id") 1262 if(data === undefined) { 1263 this.initEventIdCookies(key); 1264 } else { 1265 var data = JSON.parse(cooData); 1266 data[key] = pys_generate_token(36); 1267 Cookies.set('pys_fb_event_id', JSON.stringify(data) ); 1268 } 1269 }, 1270 1271 getEventId:function (key) { 1272 var data = Cookies.get("pys_fb_event_id"); 1273 if(data === undefined) { 1274 this.initEventIdCookies(key); 1275 data = Cookies.get("pys_fb_event_id"); 1276 } 1277 return JSON.parse(data)[key]; 1278 }, 1279 }; 1280 1281 }(options); 1282 1283 var Analytics = function (options) { 1284 1285 var initialized = false; 1286 1287 /** 1288 * Fires event 1289 * 1290 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 1291 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 1292 * @link: https://developers.google.com/gtagjs/reference/event 1293 * @link: https://developers.google.com/gtagjs/reference/parameter 1294 * 1295 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 1296 * 1297 * @param name 1298 * @param data 1299 */ 1300 function fireEvent(name, data) { 1301 1302 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) { 1303 return; 1304 } 1305 1306 var eventParams = Utils.copyProperties(data, {}); 1307 1308 var _fireEvent = function (tracking_id,name,params) { 1309 1310 params['send_to'] = tracking_id; 1311 1312 if (options.debug) { 1313 console.log('[Google Analytics #' + tracking_id + '] ' + name, params); 1314 } 1315 1316 gtag('event', name, params); 1317 1318 }; 1319 1320 options.ga.trackingIds.forEach(function (tracking_id) { 1321 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it 1322 var params = mapParamsTov4(tracking_id,name,copyParams) 1323 _fireEvent(tracking_id,name,params); 1324 }); 1325 1326 } 1327 function mapParamsTov4(tag,name,param) { 1328 //GA4 automatically collects a number of parameters for all events 1329 delete param.page_title; 1330 delete param.event_url; 1331 delete param.landing_page; 1332 // end 1333 if(isv4(tag)) { 1334 delete param.traffic_source; 1335 delete param.event_category; 1336 delete param.event_label; 1337 delete param.ecomm_prodid; 1338 delete param.ecomm_pagetype; 1339 delete param.ecomm_totalvalue; 1340 if(name === 'search') { 1341 param['search'] = param.search_term; 1342 delete param.search_term; 1343 delete param.non_interaction; 1344 delete param.dynx_itemid; 1345 delete param.dynx_pagetype; 1346 delete param.dynx_totalvalue; 1347 } 1348 } else { 1349 1350 switch (name) { 1351 1352 case 'Comment' : 1353 case 'login' : 1354 case 'sign_up' : 1355 case 'EmailClick' : 1356 case 'TelClick' : { 1357 let params = { 1358 event_category: "Key Actions", 1359 event_action: name, 1360 non_interaction: param.non_interaction, 1361 } 1362 return params; 1363 } 1364 case 'Form' : { 1365 let params = { 1366 event_category: "Key Actions", 1367 event_action: name,
1368 non_interaction: param.non_interaction, 1369 } 1370 var formClass = (typeof param.form_class != 'undefined') ? 'class: ' + param.form_class : ''; 1371 if(formClass != "") { 1372 params["event_label"] = formClass; 1373 } 1374 return params; 1375 } 1376 case 'Download' : { 1377 let params = { 1378 event_category: "Key Actions", 1379 event_action: name, 1380 event_label: param.download_name, 1381 non_interaction: param.non_interaction, 1382 } 1383 return params; 1384 } 1385 case 'TimeOnPage' : 1386 case 'PageScroll' : { 1387 let params = { 1388 event_category: "Key Actions", 1389 event_action: name, 1390 event_label: document.title, 1391 non_interaction: param.non_interaction, 1392 } 1393 return params; 1394 } 1395 case 'search' : { 1396 let params = { 1397 event_category: "Key Actions", 1398 event_action: name, 1399 event_label: param.search_term, 1400 non_interaction: param.non_interaction, 1401 } 1402 return params; 1403 } 1404 } 1405 1406 //delete standard params 1407 1408 delete param.post_type; 1409 delete param.post_id; 1410 delete param.plugin; 1411 delete param.user_role; 1412 delete param.cartlows; 1413 delete param.cartflows_flow; 1414 delete param.cartflows_step; 1415 } 1416 return param; 1417 } 1418 1419 function isv4(tag) { 1420 return tag.indexOf('G') === 0; 1421 } 1422 1423 /** 1424 * Public API 1425 */ 1426 return { 1427 tag: function() { 1428 return "ga"; 1429 }, 1430 isEnabled: function () { 1431 return options.hasOwnProperty('ga'); 1432 }, 1433 1434 disable: function () { 1435 initialized = false; 1436 }, 1437 1438 loadPixel: function () { 1439 1440 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 1441 return; 1442 } 1443 1444 Utils.loadGoogleTag(options.ga.trackingIds[0]); 1445 1446 var config = { 1447 'link_attribution': options.ga.enhanceLinkAttr, 1448 'anonymize_ip': options.ga.anonimizeIP 1449 }; 1450 1451 // Cross-Domain tracking 1452 if (options.ga.crossDomainEnabled) { 1453 config.linker = { 1454 accept_incoming: options.ga.crossDomainAcceptIncoming, 1455 domains: options.ga.crossDomainDomains 1456 }; 1457 } 1458 1459 1460 1461 // configure tracking ids 1462 options.ga.trackingIds.forEach(function (trackingId,index) { 1463 if(options.ga.isDebugEnabled.includes("index_"+index)) { 1464 config.debug_mode = true; 1465 } else { 1466 config.debug_mode = false;
1467 } 1468 if(isv4(trackingId)) { 1469 if(options.ga.disableAdvertisingFeatures) { 1470 config.allow_google_signals = false 1471 } 1472 if(options.ga.disableAdvertisingPersonalization) { 1473 config.allow_ad_personalization_signals = false 1474 } 1475 } 1476 gtag('config', trackingId, config); 1477 }); 1478 1479 initialized = true; 1480 1481 Utils.fireStaticEvents('ga'); 1482 1483 }, 1484 1485 fireEvent: function (name, data) { 1486 1487 if (!initialized || !this.isEnabled()) { 1488 return false; 1489 } 1490 1491 data.delay = data.delay || 0; 1492 data.params = data.params || {}; 1493 1494 if (data.delay === 0) { 1495 1496 fireEvent(name, data.params); 1497 1498 } else { 1499 1500 setTimeout(function (name, params) { 1501 fireEvent(name, params); 1502 }, data.delay * 1000, name, data.params); 1503 1504 } 1505 1506 return true; 1507 1508 }, 1509 1510 onCommentEvent: function (event) { 1511 this.fireEvent(event.name, event); 1512 }, 1513 1514 onDownloadEvent: function (event) { 1515 this.fireEvent(event.name, event); 1516 }, 1517 1518 onFormEvent: function (event) { 1519 this.fireEvent(event.name, event); 1520 }, 1521 1522 onWooAddToCartOnButtonEvent: function (product_id) { 1523 1524 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1525 return; 1526 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1527 1528 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1529 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 1530 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params) 1531 this.fireEvent(event.name, event); 1532 } 1533 } 1534 1535 1536 }, 1537 1538 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) { 1539 1540 window.pysWooProductData = window.pysWooProductData || []; 1541 1542 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1543 return; 1544 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1545 1546 if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) { 1547 product_id = parseInt($form.find('input[name="variation_id"]').val()); 1548 } 1549 1550 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1551 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 1552 1553 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params); 1554 if(product_type === Utils.PRODUCT_GROUPED ) { 1555 var groupValue = 0; 1556 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 1557 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 1558 var quantity = parseInt($(this).val()); 1559 if(isNaN(quantity)) { 1560 quantity = 0; 1561 } 1562 var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId]; 1563 // update quantity 1564 event.params.items.forEach(function(el,index,array) { 1565 if(el.id == childItem.content_id) { 1566 if(quantity > 0){ 1567 el.quantity = quantity; 1568 } else { 1569 array.splice(index, 1); 1570 } 1571 } 1572 }); 1573 groupValue += childItem.price * quantity; 1574 }); 1575 if(options.woo.addToCartOnButtonValueEnabled && 1576 options.woo.addToCartOnButtonValueOption !== 'global' && 1577 event.params.hasOwnProperty('ecomm_totalvalue')) { 1578 event.params.ecomm_totalvalue = groupValue; 1579 } 1580 1581 if(groupValue == 0) return;
1581 // skip if no items selected 1582 } else { 1583 // update items qty param 1584 event.params.items[0].quantity = qty; 1585 } 1586 1587 // maybe customize value option 1588 if (options.woo.addToCartOnButtonValueEnabled && 1589 options.woo.addToCartOnButtonValueOption !== 'global' && 1590 product_type !== Utils.PRODUCT_GROUPED) 1591 { 1592 if(event.params.hasOwnProperty('ecomm_totalvalue')) { 1593 event.params.ecomm_totalvalue = event.params.items[0].price * qty; 1594 } 1595 1596 } 1597 1598 1599 this.fireEvent(event.name, event); 1600 } 1601 } 1602 1603 }, 1604 1605 onWooRemoveFromCartEvent: function (event) { 1606 1607 this.fireEvent(event.name, event); 1608 1609 }, 1610 1611 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 1612 1613 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1614 return; 1615 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 1616 1617 1618 if (window.pysEddProductData.hasOwnProperty(download_id)) { 1619 1620 var index; 1621 1622 if (price_index) { 1623 index = download_id + '_' + price_index; 1624 } else { 1625 index = download_id; 1626 } 1627 1628 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 1629 if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) { 1630 1631 Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params); 1632 1633 // update items qty param 1634 event.params.items[0].quantity = qty; 1635 1636 this.fireEvent(event.name,event); 1637 1638 } 1639 } 1640 1641 } 1642 1643 }, 1644 1645 onEddRemoveFromCartEvent: function (event) { 1646 this.fireEvent(event.name, event); 1647 }, 1648 onPageScroll: function (event) { 1649 this.fireEvent(event.name, event); 1650 }, 1651 onTime: function (event) { 1652 this.fireEvent(event.name, event); 1653 }, 1654 1655 }; 1656 1657 }(options); 1658 1659 window.pys = window.pys || {}; 1660 window.pys.Facebook = Facebook; 1661 window.pys.Analytics = Analytics; 1662 window.pys.Utils = Utils; 1663 1664 1665 1666 1667 $(document).ready(function () { 1668 1669 if($("#pys_late_event").length > 0) { 1670 var events = JSON.parse($("#pys_late_event").attr("dir")); 1671 for(var key in events) { 1672 var event = {}; 1673 event[events[key].e_id] = [events[key]]; 1674 if(options.staticEvents.hasOwnProperty(key)) { 1675 Object.assign(options.staticEvents[key], event); 1676 } else { 1677 options.staticEvents[key] = event; 1678 } 1679 1680 } 1681 } 1682 1683 var Pinterest = Utils.setupPinterestObject(); 1684 var Bing = Utils.setupBingObject(); 1685 1686 Utils.setupGdprCallbacks(); 1687 // page scroll event 1688 if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll") 1689 ) { 1690 1691 var singlePageScroll = function () { 1692 1693 1694 var docHeight = $(document).height() - $(window).height(); 1695 var isFired = false; 1696 1697 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) { 1698 var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll); 1699 for(var i = 0;i<pixels.length;i++) { 1700 var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]); 1701 var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions 1702 1703 if(scroll < $(window).scrollTop()) { 1704 Utils.copyProperties(Utils.getRequestParam
1704s(), event.params); 1705 getPixelBySlag(pixels[i]).onPageScroll(event); 1706 isFired = true 1707 } 1708 } 1709 } 1710 if(isFired) { 1711 $(document).off("scroll",singlePageScroll); 1712 } 1713 } 1714 $(document).on("scroll",singlePageScroll); 1715 } 1716 1717 1718 if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) { 1719 var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page); 1720 var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel 1721 setTimeout(function(){ 1722 for(var i = 0;i<pixels.length;i++) { 1723 var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]); 1724 Utils.copyProperties(Utils.getRequestParams(), event.params); 1725 getPixelBySlag(pixels[i]).onTime(event); 1726 } 1727 },time*1000); 1728 } 1729 1730 // setup Click Event 1731 if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) { 1732 1733 $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) { 1734 1735 var $elem = $(this); 1736 1737 // Download 1738 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") 1739 ) { 1740 var isFired = false; 1741 if ($elem.is('a')) { 1742 var href = $elem.attr('href'); 1743 if (typeof href !== "string") { 1744 return; 1745 } 1746 href = href.trim(); 1747 var extension = Utils.getLinkExtension(href); 1748 var track_download = false; 1749 1750 if (extension.length > 0) { 1751 1752 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) { 1753 var pixels = Object.keys(options.dynamicEvents.automatic_event_download); 1754 for (var i = 0; i < pixels.length; i++) { 1755 var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]); 1756 var extensions = event.extensions; 1757 if (extensions.includes(extension)) { 1758 1759 if(pixels[i] == "tiktok") { 1760 getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event); 1761 } else { 1762 if (options.enable_remove_download_url_param) { 1763 href = href.split('?')[0]; 1764 } 1765 event.params.download_url = href; 1766 event.params.download_type = extension; 1767 event.params.download_name = Utils.getLinkFilename(href); 1768 getPixelBySlag(pixels[i]).onDownloadEvent(event); 1769 } 1770 1771 isFired = true; 1772 } 1773 } 1774 } 1775 } 1776 } 1777 if(isFired) { // prevent duplicate events on the same element 1778 return; 1779 } 1780 } 1781 }); 1782 } 1783 1784 1785 // setup Dynamic events 1786 $.each(options.triggerEventTypes, function (triggerType, events) { 1787 1788 $.each(events, function (eventId, triggers) { 1789 1790 switch (triggerType) { 1791 case 'url_click': 1792 //@see: Utils.setupURLClickEvents() 1793 break; 1794 1795 case 'css_click': 1796 Utils.setupCSSClickEvents(eventId, triggers); 1797 break; 1798 1799 case 'css_mouseover': 1800 Utils.setupMouseOverClickEvents(eventId, triggers); 1801 break; 1802 1803 case 'scroll_pos': 1804 Utils.setupScrollPosEvents(eventId, triggers); 1805 break; 1806 case 'comment': 1807 Utils.setupCommentEvents(eventId, triggers); 1808 break; 1809 } 1810 1811 }); 1812 1813 }); 1814 // setup WooCommerce events 1815 if (options.woo.enabled) { 1816 1817 // WooCommerce AddToCart 1818 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click") 1819 && options.woo.hasOwnProperty("addToCartCatchMethod") 1820 && options.woo.addToCartCatchMethod === "add_cart_js" 1821 ) { 1822 1823 // Loop, any kind of "simple" product, except external 1824 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 1825 1826 var product_id = $(this).data('product_id'); 1827 1828 if (typeof product_id !== 'undefined') { 1829 Facebook.onWooAddToCartOnButtonEvent(product_id); 1830 Analytics.onWooAddToCartOnButtonEvent(product_id); 1831 Pinterest.onWooAddToCartOnButtonEvent(product_id); 1832 Bing.onWooAddToCartOnButtonEvent(product_id); 1833 } 1834 1835 }); 1836 1837 // Single Product 1838 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 1839 // $(document) not work 1840 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 1841 1842 var $button = $(this); 1843 1844 if ($button.hasClass('disabled')) { 1845 return; 1846 } 1847 1848 var $form = $button.closest('form'); 1849 1850 var product_type = Utils.PRODUCT_SIMPLE; 1851 1852 if ($form.length === 0) { 1853 return ; 1854 } else if ($form.hasClass('variations_form')) { 1855 product_type = Utils.PRODUCT_VARIABLE; 1856 } else if($form.hasClass('bundle_form')) { 1857 product_type = Utils.PRODUCT_BUNDLE; 1858 } else if($form.hasClass('grouped_form')) { 1859 product_type = Utils.PRODUCT_GROUPED; 1860 } 1861 1862 1863 1864 1865 var product_id; 1866 var qty; 1867 1868 if (product_type === Utils.PRODUCT_GROUPED) { 1869 qty = 1; 1870 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 1871 } else if (product_type === Utils.PRODUCT_VARIABLE) { 1872 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 1873 var qtyTag = $form.find('input[name="quantity"]'); 1874 if(qtyTag.length <= 0) { 1875 qtyTag = $form.find('select[name="quantity"]'); 1876 } 1877 qty = parseInt(qtyTag.val()); 1878 } else { 1879 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 1880 var qtyTag = $form.find('input[name="quantity"]'); 1881 if(qtyTag.length <= 0) { 1882 qtyTag = $form.find('select[name="quantity"]'); 1883 } 1884 qty = parseInt(qtyTag.val()); 1885 } 1886 1887 Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 1888 Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form); 1889 1890 Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 1891 Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form); 1892 1893 }); 1894 1895 } 1896 1897 // WooCommerce RemoveFromCart 1898 if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) { 1899 1900 $('body').on('click', options.woo.removeFromCartSelector, function (e) { 1901 1902 var $a = $(e.currentTarget), 1903 href = $a.attr('href'); 1904 1905 // extract cart item hash from remove button URL 1906 var regex = new RegExp("[\\?&]remove_item=([^&#]*)"), 1907 results = regex.exec(href); 1908 1909 if (results !== null) { 1910 1911 var item_hash = results[1]; 1912 1913 if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) { 1914 var events = options.dynamicEvents["woo_remove_from_cart"][item_hash]; 1915 Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events) 1916 } 1917 1918 } 1919 1920 }); 1921 } 1922 } 1923 1924 // setup EDD events 1925 if (options.edd.enabled) { 1926 1927 // EDD AddToCart 1928 if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) { 1929 1930 $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) { 1931 1932 var $button = $(this); 1933 var $form = $button.closest('form'); 1934 var variable_price = $button.data('variablePrice'); // yes/no 1935 var price_mode = $button.data('priceMode'); // single/multi 1936 var ids = []; 1937 var quantities = []; 1938 var qty; 1939 var id; 1940 1941 if (variable_price === 'yes' && price_mode === 'multi') { 1942 1943 id = $form.find('input[name="download_id"]').val(); 1944 1945 // get selected variants 1946 $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) { 1947 ids.push(id + '_' + $(el).val()); 1948 }); 1949 1950 // get qty for selected variants 1951 $.each(ids, function (i, variant_id) { 1952 1953 var variant_index = variant_id.split('_', 2); 1954 qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val(); 1955 1956 if (typeof qty !== 'undefined') { 1957 quantities.push(qty); 1958 } else { 1959 quantities.push(1); 1960 } 1961 1962 }); 1963 1964 } else if (variable_price === 'yes' && price_mode === 'single') { 1965 1966 id = $form.find('input[name="download_id"]').val(); 1967 ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val()); 1968 1969 qty = $form.find('input[name="edd_download_quantity"]').val(); 1970 1971 if (typeof qty !== 'undefined') { 1972 quantities.push(qty); 1973 } else { 1974 quantities.push(1); 1975 } 1976 1977 } else { 1978 1979 ids.push($button.data('downloadId')); 1980 1981 qty = $form.find('input[name="edd_download_quantity"]').val(); 1982 1983 if (typeof qty !== 'undefined') { 1984 quantities.push(qty); 1985 } else { 1986 quantities.push(1); 1987 } 1988 } 1989 1990 // fire event for each download/variant 1991 $.each(ids, function (i, download_id) { 1992 1993 var q = parseInt(quantities[i]); 1994 var variant_index = download_id.toString().split('_', 2); 1995 var price_index; 1996 1997 if (variant_index.length === 2) { 1998 download_id = variant_index[0]; 1999 price_index = variant_index[1]; 2000 } 2001 2002 Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2003 Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2004 Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2005 Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q); 2006 2007 }); 2008 2009 }); 2010 2011 } 2012 2013 2014 // EDD RemoveFromCart 2015 if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) { 2016 2017 $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) { 2018 2019 var href = $(this).attr('href'); 2020 if(href) { 2021 var key = href.substring(href.indexOf('=') + 1).charAt(0); 2022 if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) { 2023 var events = options.dynamicEvents.edd_remove_from_cart[key]; 2024 Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events) 2025 } 2026 } 2027 }); 2028 2029 } 2030 2031 } 2032 2033 // setup Comment Event 2034 if (options.dynamicEvents.hasOwnProperty("automatic_event_c
2034omment") 2035 ) { 2036 2037 $('form.comment-form').on("submit",function () { 2038 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) { 2039 var pixels = Object.keys(options.dynamicEvents.automatic_event_comment); 2040 for (var i = 0; i < pixels.length; i++) { 2041 var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]); 2042 Utils.copyProperties(Utils.getRequestParams(), event.params); 2043 getPixelBySlag(pixels[i]).onCommentEvent(event); 2044 } 2045 } 2046 }); 2047 2048 } 2049 2050 2051 // setup Form Event 2052 if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 2053 2054 $(document).onFirst('submit', 'form', function (e) { 2055 2056 var $form = $(this); 2057 2058 // exclude WP forms 2059 if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') { 2060 return; 2061 } 2062 2063 // exclude Woo forms 2064 if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') || 2065 $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) { 2066 return; 2067 } 2068 2069 // exclude EDD forms 2070 if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) { 2071 return; 2072 } 2073 2074 var params = { 2075 form_id: $form.attr('id'), 2076 form_class: $form.attr('class'), 2077 text: $form.find('[type="submit"]').is('input') ? 2078 $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text() 2079 }; 2080 2081 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 2082 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 2083 for (var i = 0; i < pixels.length; i++) { 2084 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 2085 2086 if(pixels[i] === "tiktok") { 2087 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 2088 } else { 2089 Utils.copyProperties(params, event.params,) 2090 Utils.copyProperties(Utils.getRequestParam
2090s(), event.params); 2091 getPixelBySlag(pixels[i]).onFormEvent(event); 2092 } 2093 } 2094 } 2095 }); 2096 2097 //Forminator 2098 $(document).on( 'forminator:form:submit:success', function( formData ){ 2099 var params = { 2100 form_id: $(formData.target).find('input[name="form_id"]').val(), 2101 text: $(formData.target).find('.forminator-button-submit').text() 2102 }; 2103 2104 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 2105 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 2106 for (var i = 0; i < pixels.length; i++) { 2107 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 2108 Utils.copyProperties(params, event.params) 2109 Utils.copyProperties(Utils.getRequestParams(), event.params); 2110 getPixelBySlag(pixels[i]).onFormEvent(event); 2111 } 2112 } 2113 }); 2114 2115 // Ninja Forms 2116 $(document).onFirst('nfFormSubmitResponse', function (e, data) { 2117 2118 var params = { 2119 form_id: data.response.data.form_id, 2120 text: data.response.data.settings.title 2121 }; 2122 2123 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 2124 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 2125 for(var i = 0;i<pixels.length;i++) { 2126 var event = options.dynamicEvents.automatic_event_form[pixels[i]]; 2127 Utils.copyProperties(params,event.params) 2128 Utils.copyProperties(Utils.getRequestParam
2128s(), event.params); 2129 getPixelBySlag(pixels[i]).onFormEvent(event); 2130 } 2131 } 2132 2133 }); 2134 2135 } 2136 2137 2138 // load pixel APIs 2139 Utils.loadPixels(); 2140 2141 }); 2142 2143}(jQuery, pysOptions); 2144 2145function pys_generate_token(length){ 2146 //edit the token allowed characters 2147 var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split(""); 2148 var b = []; 2149 for (var i=0; i<length; i++) { 2150 var j = (Math.random() * (a.length-1)).toFixed(0); 2151 b[i] = a[j]; 2152 } 2153 return b.join(""); 2154} 2155 2156function getBundlePriceOnSingleProduct(data) { 2157 var items_sum = 0; 2158 jQuery(".bundle_form .bundled_product").each(function(index){ 2159 var id = jQuery(this).find(".cart").data("bundled_item_id"); 2160 var item_price = data.prices[id]; 2161 var item_quantity = jQuery(this).find(".bundled_qty").val(); 2162 if(!jQuery(this).hasClass("bundled_item_optional") || 2163 jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) { 2164 items_sum += item_price*item_quantity; 2165 } 2166 }); 2167 return items_sum; 2168} 2169 2170function getPixelBySlag(slug) { 2171 switch (slug) { 2172 case "facebook": return window.pys.Facebook; 2173 case "ga": return window.pys.Analytics; 2174 case "bing": return window.pys.Bing; 2175 case "pinterest": return window.pys.Pinterest; 2176 } 2177}
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.