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