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 56if (!String.prototype.startsWith) { 57 Object.defineProperty(String.prototype, 'startsWith', { 58 enumerable: false, 59 configurable: false, 60 writable: false, 61 value: function (searchString, position) { 62 position = position || 0; 63 return this.indexOf(searchString, position) === position; 64 } 65 }); 66} 67 68if (!String.prototype.trim) { 69 (function () { 70 String.prototype.trim = function () { 71 return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); 72 }; 73 })(); 74} 75 76! function ($, options) { 77 78 if (options.debug) { 79 console.log('PYS:', options); 80 } 81 82 var dummyPinterest = function () { 83 84 /** 85 * Public API 86 */ 87 return { 88 tag: function() { 89 return "pinterest"; 90 }, 91 isEnabled: function () {}, 92 93 disable: function () {}, 94 95 loadPixel: function () {}, 96 97 fireEvent: function (name, data) { 98 return false; 99 }, 100 101 onAdSenseEvent: function (event) {}, 102 103 onClickEvent: function (params) {}, 104 105 onWatchVideo: function (params) {}, 106 107 onCommentEvent: function (event) {}, 108 109 onFormEvent: function (params) {}, 110 111 onDownloadEvent: function (params) {}, 112 113 114 115 onWooAddToCartOnButtonEvent: function (product_id) {}, 116 117 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {}, 118 119 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 120 121 onWooAffiliateEvent: function (product_id) {}, 122 123 onWooPayPalEvent: function (event) {}, 124 125 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 126 127 onEddRemoveFromCartEvent: function (item) {}, 128 129 onPageScroll: function (event) {}, 130 onTime: function (event) { 131 132 }, 133 134 } 135 136 }(); 137 138 var dummyBing = function () { 139 140 /** 141 * Public API 142 */ 143 return { 144 tag: function() { 145 return "bing"; 146 }, 147 isEnabled: function () {}, 148 149 disable: function () {}, 150 151 loadPixel: function () {}, 152 153 fireEvent: function (name, data) { 154 return false;
155 }, 156 157 onAdSenseEvent: function (event) {}, 158 159 onClickEvent: function (params) {}, 160 161 onWatchVideo: function (params) {}, 162 163 onCommentEvent: function (event) {}, 164 165 onFormEvent: function (params) {}, 166 167 onDownloadEvent: function (params) {}, 168 169 170 onWooAddToCartOnButtonEvent: function (product_id) {}, 171 172 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {}, 173 174 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 175 176 onWooAffiliateEvent: function (product_id) {}, 177 178 onWooPayPalEvent: function (event) {}, 179 180 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 181 182 onEddRemoveFromCartEvent: function (item) {}, 183 onPageScroll: function (event) {}, 184 onTime: function (event) { 185 186 }, 187 } 188 189 }(); 190 191 var Utils = function (options) { 192 193 194 var Pinterest = dummyPinterest; 195 196 var Bing = dummyBing; 197 198 var gtag_loaded = false; 199 200 201 202 function loadPixels() { 203 204 if (!options.gdpr.all_disabled_by_api) { 205 if (!options.gdpr.tiktok_disabled_by_api) { 206 TikTok.loadPixel(); 207 } 208 209 if (!options.gdpr.facebook_disabled_by_api) { 210 Facebook.loadPixel(); 211 } 212 213 if (!options.gdpr.analytics_disabled_by_api) { 214 Analytics.loadPixel(); 215 } 216 217 if (!options.gdpr.google_ads_disabled_by_api) { 218 GAds.loadPixel(); 219 } 220 221 if (!options.gdpr.pinterest_disabled_by_api) { 222 Pinterest.loadPixel(); 223 } 224 225 if (!options.gdpr.bing_disabled_by_api) { 226 Bing.loadPixel(); 227 } 228 229 } 230 231 } 232 233 /** 234 * WATCHVIDEO UTILS 235 */ 236 237 function isJSApiAttrEnabled(url) { 238 return url.indexOf('enablejsapi') > -1; 239 } 240 241 function isOriginAttrEnabled(url) { 242 return url.indexOf('origin') > -1; 243 } 244 245 // Returns key/value pairs of percentages: number of seconds to achieve 246 function getVideoCompletionMarks(duration) { 247 248 var marks = {}; 249 var points = [0, 10, 50, 90, 100]; 250 251 for (var i = 0; i < points.length; i++) { 252 253 var _point = points[i]; 254 var _mark = _point + '%'; 255 var _time = duration * _point / 100; 256 257 if (_point === 100) { 258 _time = _time - 1; 259 } 260 261 // 10% => 123 262 marks[_mark] = Math.floor(_time); 263 264 } 265 266 return marks; 267 268 } 269 270 // Determine if the element is a YouTube video or not 271 function tagIsYouTubeVideo(tag) { 272 var src = tag.src || ''; 273 return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1; 274 } 275 276 function tagIsYouTubeAsyncVideo(tag) { 277 if(tag.src && tag.src.indexOf("data:image") !== -1) return false; // video is loaded 278 var keys = Object.keys(tag.dataset); 279 for(var i = 0;i<keys.length;i++) { 280 if(keys[i].toLowerCase().indexOf("src") > -1) { 281 var src = tag.dataset[keys[i]]; 282 return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1; 283 } 284 } 285 return false; //not find src 286 } 287 288 // Turn embed objects into iframe objects and ensure they have the right parameters 289 function normalizeYouTubeIframe(tag) { 290 291 var loc = window.location; 292 var a = document.createElement('a'); 293 a.href = tag.src; 294 a.hostname = 'www.youtube.com'; 295 a.protocol = loc.protocol; 296 var tmpPathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname; // IE10 shim 297 298 if (!isJSApiAttrEnabled(a.search)) { 299 a.search = (a.search.length > 0 ? a.search + '&' : '') + 'enablejsapi=1'; 300 } 301 302 // for security reasons, YouTube wants an origin parameter set that matches our hostname
303 if (!isOriginAttrEnabled(a.search) && loc.hostname.indexOf('localhost') === -1) { 304 305 var port = loc.port ? ':' + loc.port : ''; 306 var origin = loc.protocol + '%2F%2F' + loc.hostname + port; 307 308 a.search = a.search + '&origin=' + origin; 309 310 } 311 312 if (tag.type === 'application/x-shockwave-flash') { 313 314 var newIframe = document.createElement('iframe'); 315 newIframe.height = tag.height; 316 newIframe.width = tag.width; 317 tmpPathname = tmpPathname.replace('/v/', '/embed/'); 318 319 tag.parentNode.parentNode.replaceChild(newIframe, tag.parentNode); 320 321 tag = newIframe; 322 323 } 324 325 a.pathname = tmpPathname; 326 327 if (tag.src !== a.href + a.hash) { 328 tag.src = a.href + a.hash; 329 } 330 331 return tag; 332 333 } 334 335 // Add event handlers for events emitted by the YouTube API 336 function addYouTubeEvents(iframe) { 337 338 var player = YT.get(iframe.id); 339 340 if (!player) { 341 player = new YT.Player(iframe, {}); 342 } 343 344 if (typeof iframe.pauseFlag === 'undefined') { 345 346 iframe.pauseFlag = false; 347 player.addEventListener('onStateChange', function (evt) { 348 onYouTubePlayerStateChange(evt, iframe); 349 }); 350 351 } 352 353 } 354 355 function addDynYouTubeVideos(el) { 356 // We only bind to iFrames with a YouTube URL with the enablejsapi=1 and 357 // origin=<<hostname>> parameters 358 if (el.tagName === 'IFRAME' 359 && tagIsYouTubeVideo(el) 360 && isJSApiAttrEnabled(el.src) 361 && isOriginAttrEnabled(el.src)) 362 { 363 addYouTubeEvents(el); 364 } 365 } 366 367 // Event handler for events emitted from the YouTube API 368 function onYouTubePlayerStateChange(evt, iframe) { 369 370 var stateIndex = evt.data; 371 var player = evt.target; 372 var targetVideoUrl = player.getVideoUrl(); 373 var targetVideoId = targetVideoUrl.match(/[?&]v=([^&#]*)/)[1]; // Extract the ID 374 var playerState = player.getPlayerState(); 375 var marks = getVideoCompletionMarks(player.getDuration()); 376 377 iframe.playTracker = iframe.playTracker || {}; 378 379 if (playerState === YT.PlayerState.PLAYING && !iframe.timer) { 380 381 clearInterval(iframe.timer); 382 383 // check every second to see if we've hit any of our percentage viewed marks 384 iframe.timer = setInterval(function () { 385 checkYouTubeCompletion(player, marks, iframe.videoId); 386 }, 1000); 387 388 } else { 389 390 clearInterval(iframe.timer); 391 iframe.timer = false; 392 393 } 394 395 // playlist edge-case handler 396 if (stateIndex === YT.PlayerState.PLAYING) { 397 iframe.playTracker[targetVideoId] = true; 398 iframe.videoId = targetVideoId; 399 iframe.pauseFlag = false; 400 } 401 402 if (!iframe.playTracker[iframe.videoId]) { 403 return false; // this video hasn't started yet, so this is spam 404 } 405 406 if (stateIndex === YT.PlayerState.PAUSED) { 407 408 if (!iframe.pauseFlag) { 409 iframe.pauseFlag = true; 410 } else { 411 return false; // we don't want to fire consecutive pause events 412 } 413 414 } 415 416 } 417 418 // Trigger event if YouTube video mark was reached 419 function checkYouTubeCompletion(player, marks, videoId) { 420 421 var currentTime = player.getCurrentTime(); 422 423 player[videoId] = player[videoId] || {}; 424 425 for (var key in marks) { 426 427 if (marks[key] <= currentTime && !player[videoId][key]) { 428 player[videoId][key] = true; 429 430 var data = player.getVideoData(); 431 432 if (key === '0%') { 433 key = 'play'; 434 } 435 436 var params = { 437 video_type: 'youtube', 438 video_id: videoId, 439 video_title: data.title, 440 }; 441 442 // Auto 443 if(options.automatic.enable_video 444 && options.automatic.enable_youtube 445 && options.dynamicEvents.hasOwnProperty("automatic_event_video") 446 ) { 447 var pixels = Object.keys(options.dynamicEvents.automatic_event_video); 448 449 for (var i = 0; i < pixels.length; i++) { 450 var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]); 451 event.params["progress"] = key 452 Utils.copyProperties(params, event.params) 453 Utils.copyProperties(Utils.getRequestParam
453s(), event.params); 454 getPixelBySlag(pixels[i]).onWatchVideo(event); 455 } 456 } 457 458 if(key == "play") { 459 460 $.each(options.triggerEventTypes, function (triggerType, events) { 461 $.each(events, function (eventId, triggers) { 462 switch (triggerType) { 463 case 'video_play': 464 Utils.fireTriggerEvent(eventId); 465 break; 466 } 467 468 }); 469 }); 470 } 471 472 } 473 474 } 475 476 } 477 478 // Determine if the element is a Vimeo video or not 479 function tagIsVimeoVideo(tag) { 480 var src = tag.src || ''; 481 return src.indexOf('player.vimeo.com/video/') > -1; 482 } 483 484 function tagIsAsincVimeoVideo(tag) { 485 if(tag.src) return false; // video is loaded 486 var keys = Object.keys(tag.dataset); 487 for(var i = 0;i<keys.length;i++) { 488 if(keys[i].toLowerCase().indexOf("src") > -1) { 489 var src = tag.dataset[keys[i]]; 490 return src.indexOf('player.vimeo.com/video/') > -1; 491 } 492 } 493 return false; //not find src 494 } 495 496 function attachVimeoPlayerToTag(tag) { 497 var player = new Vimeo.Player(tag); 498 499 player.getDuration().then(function (pl,seconds) { 500 pl.pysMarks = getVideoCompletionMarks(seconds); 501 }.bind(null,player)); 502 503 player.getVideoTitle().then(function (pl,title) { 504 pl.pysVideoTitle = title; 505 }.bind(null,player)); 506 507 player.getVideoId().then(function (pl,id) { 508 pl.pysVideoId = id; 509 }.bind(null,player)); 510 511 player.pysCompletedMarks = {}; 512 513 player.on('play', function () { 514 515 if (this.pysTimer) { 516 return; 517 } 518 519 clearInterval(this.pysTimer); 520 521 var player = this; 522 523 this.pysTimer = setInterval(function () { 524 checkVimeoCompletion(player); 525 }, 1000); 526 527 }); 528 529 player.on('pause', function () { 530 clearInterval(this.pysTimer); 531 this.pysTimer = false; 532 }); 533 534 player.on('ended', function () { 535 clearInterval(this.pysTimer); 536 this.pysTimer = false; 537 }); 538 } 539 540 // Trigger event if Vimeo video mark was reached 541 function checkVimeoCompletion(player) { 542 543 player.getCurrentTime().then(function (seconds) { 544 545 for (var key in player.pysMarks) { 546 547 if (player.pysMarks[key] <= seconds && !player.pysCompletedMarks[key]) { 548 549 player.pysCompletedMarks[key] = true; 550 551 if (key === '0%') { 552 key = 'play'; 553 } 554 555 var params = { 556 video_type: 'vimeo', 557 video_id: player.pysVideoId, 558 video_title: player.pysVideoTitle, 559 }; 560 561 // Auto 562 if(options.automatic.enable_video 563 && options.automatic.enable_vimeo 564 && options.dynamicEvents.hasOwnProperty("automatic_event_video") 565 ) { 566 var pixels = Object.keys(options.dynamicEvents.automatic_event_video); 567 568 for (var i = 0; i < pixels.length; i++) { 569 var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]); 570 event.params["progress"] = key 571 Utils.copyProperties(params, event.params,); 572 Utils.copyProperties(Utils.getRequestParam
572s(), event.params); 573 getPixelBySlag(pixels[i]).onWatchVideo(event); 574 } 575 } 576 577 if(key == "play") { 578 $.each(options.triggerEventTypes, function (triggerType, events) { 579 $.each(events, function (eventId, triggers) { 580 switch (triggerType) { 581 case 'video_play': 582 Utils.fireTriggerEvent(eventId); 583 break; 584 } 585 586 }); 587 }); 588 } 589 } 590 591 } 592 593 }); 594 595 } 596 597 /** 598 * COOKIES UTILS 599 */ 600 601 var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; 602 603 var requestParams = []; 604 605 function validateEmail(email) { 606 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 607 return re.test(email); 608 } 609 function getDomain(url) { 610 611 url = url.replace(/(https?:\/\/)?(www.)?/i, ''); 612 613 if (url.indexOf('/') !== -1) { 614 return url.split('/')[0]; 615 } 616 617 return url; 618 } 619 620 function getTrafficSource() { 621 622 try { 623 624 var referrer = document.referrer.toString(), 625 source; 626 627 var direct = referrer.length === 0; 628 var internal = direct ? false : referrer.indexOf(options.siteUrl) === 0; 629 var external = !direct && !internal; 630 var cookie = typeof Cookies.get('pysTrafficSource') === 'undefined' ? false : Cookies.get('pysTrafficSource'); 631 632 if (external === false) { 633 source = cookie ? cookie : 'direct'; 634 } else { 635 source = cookie && cookie === referrer ? cookie : referrer; 636 } 637 638 if (source !== 'direct') { 639 // leave only domain (Issue #70) 640 return getDomain(source); 641 } else { 642 return source; 643 } 644 645 } catch (e) { 646 console.error(e); 647 return 'direct'; 648 } 649 650 } 651 652 /** 653 * Return query variables object with where property name is query variable 654 * and property value is query variable value. 655 */ 656 function getQueryVars() { 657 658 try { 659 660 var result = {}, 661 tmp = []; 662 663 window.location.search 664 .substr(1) 665 .split("&") 666 .forEach(function (item) { 667 668 tmp = item.split('='); 669 670 if (tmp.length > 1) { 671 result[tmp[0]] = tmp[1]; 672 } 673 674 }); 675 676 return result; 677 678 } catch (e) { 679 console.error(e); 680 return {}; 681 } 682 683 } 684 685 function getLandingPage() { 686 if(Cookies.get('pys_landing_page') === 'undefined') { 687 return ""; 688 } else { 689 return Cookies.get('pys_landing_page'); 690 } 691 } 692 693 /** 694 * Return UTM terms from request query variables or from cookies. 695 */ 696 function getUTMs() { 697 698 try { 699 700 var terms = []; 701 var queryVars = getQueryVars(); 702 703 $.each(utmTerms, function (index, name) { 704 705 var value; 706 707 if (Cookies.get('pys_' + name)) { 708 value = Cookies.get('pys_' + name); 709 // do not allow email in request params (Issue #70) 710 terms[name] = filterEmails(value); 711 } else if (queryVars.hasOwnProperty(name)) { 712 value = queryVars[name]; 713 // do not allow email in request params (Issue #70) 714 terms[name] = filterEmails(value); 715 } 716 717 }); 718 719 return terms; 720 721 } catch (e) { 722 console.error(e); 723 return []; 724 } 725 726 } 727 728 function getDateTime() { 729 var dateTime = new Array(); 730 var date = new Date(), 731 days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 732 months = ['January', 'February', 'March', 'April', 'May', 'June', 733 'July', 'August', 'September', 'October', 'November', 'December' 734 ], 735 hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08', 736 '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17', 737 '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24' 738 ]; 739 dateTime.push(hours[date.getHours()]); 740 dateTime.push(days[date.getDay()]); 741 dateTime.push(months[date.getMonth()]); 742 return dateTime; 743 } 744 745 function filterEmails(value) { 746 return validateEmail(value) ? undefined : value; 747 } 748 749 /** 750 * PUBLIC API 751 */ 752 return { 753 754 PRODUCT_SIMPLE : 0, 755 PRODUCT_VARIABLE : 1, 756 PRODUCT_BUNDLE : 2, 757 PRODUCT_GROUPED : 3, 758 759 fireEventForAllPixel:function(functionName,events){ 760 if (events.hasOwnProperty(Facebook.tag())) 761 Facebook[functionName](events[Facebook.tag()]); 762 if (events.hasOwnProperty(Analytics.tag())) 763 Analytics[functionName](events[Analytics.tag()]); 764 if (events.hasOwnProperty(GAds.tag())) 765 GAds[functionName](events[GAds.tag()]); 766 if (events.hasOwnProperty(Pinterest.tag())) 767 Pinterest[functionName](events[Pinterest.tag()]); 768 if (events.hasOwnProperty(Bing.tag())) 769 Bing[functionName](events[Bing.tag()]); 770 if (events.hasOwnProperty(TikTok.tag())) 771 TikTok[functionName](events[TikTok.tag()]); 772 }, 773 774 getQueryValue:function (name){ 775 return getQueryVars()[name]; 776 }, 777 778 filterEmails: function (value) { 779 return filterEmails(value); 780 }, 781 782 setupPinterestObject: function () { 783 Pinterest = window.pys.Pinterest || Pinterest; 784 return Pinterest; 785 }, 786 787 setupBingObject: function () { 788 Bing = window.pys.Bing || Bing; 789 return Bing; 790 }, 791 792 // Clone all object members to another and return it 793 copyProperties: function (from, to) { 794 for (var key in from) { 795 if("function" == typeof from[key]) { 796 continue; 797 } 798 to[key] = from[key]; 799 } 800 return to; 801 }, 802 803 clone: function(obj) { 804 var copy; 805 806 // Handle the 3 simple types, and null or undefined 807 if (null == obj || "object" != typeof obj) return obj; 808 809 // Handle Date 810 if (obj instanceof Date) { 811 copy = new Date(); 812 copy.setTime(obj.getTime()); 813 return copy; 814 } 815 816 // Handle Array 817 if (obj instanceof Array) { 818 copy = []; 819 for (var i = 0, len = obj.length; i < len; i++) { 820 if("function" == typeof obj[i]) { 821 continue; 822 } 823 copy[i] = Utils.clone(obj[i]); 824 } 825 return copy; 826 } 827 828 // Handle Object 829 if (obj instanceof Object) { 830 copy = {}; 831 for (var attr in obj) { 832 if (obj.hasOwnProperty(attr)) { 833 if("function" == typeof obj[attr]) { 834 continue; 835 } 836 copy[attr] = Utils.clone(obj[attr]); 837 } 838 } 839 return copy; 840 } 841 842 return obj; 843 }, 844 845 // Returns array of elements with given tag name 846 getTagsAsArray: function (tag) { 847 return [].slice.call(document.getElementsByTagName(tag)); 848 }, 849 850 /** 851 * Load and initialize YouTube API 852 * 853 * @link: https://developers.google.com/youtube/iframe_api_reference 854 */ 855 initYouTubeAPI: function () { 856 857 // maybe load YouTube JS API 858 if (typeof window.YT === 'undefined') { 859 var tag = document.createElement('script'); 860 tag.src = '//www.youtube.com/iframe_api'; 861 var firstScriptTag = document.getElementsByTagName('script')[0]; 862 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 863 } 864 865 // initialize when API is ready 866 window.onYouTubeIframeAPIReady = function () { 867 868 // collect all possible YouTube tags 869 var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed')); 870 871 // turn videos into trackable videos with events 872 for (var i = 0; i < potentialVideos.length; i++) { 873 var video = potentialVideos[i]; 874 if (tagIsYouTubeVideo(video)) { 875 var iframe = normalizeYouTubeIframe(video); 876 addYouTubeEvents(iframe); 877 } else { 878 if(tagIsYouTubeAsyncVideo(video)) { 879 video.addEventListener("load", function(evt) { 880 var iframe = normalizeYouTubeIframe(evt.currentTarget); 881 addYouTubeEvents(iframe); 882 }); 883 } 884 } 885 } 886 887 888 889 var targets = document.querySelectorAll('.elementor-widget-video .elementor-wrapper'); 890 891 const config = { 892 attributes: false, 893 childList: true, 894 subtree: true 895 }; 896 897 const callback = function(mutationsList, observer) { 898 for (let mutation of mutationsList) { 899 if (mutation.type === 'childList') { 900 for(var m = 0;m<mutation.addedNodes.length;m++) { 901 addDynYouTubeVideos(mutation.addedNodes[m]); 902 } 903 } 904 } 905 }; 906 // observe elementator widget-video and add event when it add iframe 907 for(var i=0;i<targets.length;i++) { 908 const observer = new MutationObserver(callback); 909 observer.observe(targets[i], config);//maybe remove before add 910 } 911 912 913 }; 914 915 }, 916 917 /** 918 * Load and initialize Vimeo API 919 * 920 * @link: https://github.com/vimeo/player.js 921 */ 922 initVimeoAPI: function () { 923 924 925 $(document).ready(function () { 926 927 var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed')); 928 929 for (var i = 0; i < potentialVideos.length; i++) { 930 var tag = potentialVideos[i]; 931 if (tagIsVimeoVideo(tag)) { 932 attachVimeoPlayerToTag(tag); 933 } else { 934 if (tagIsAsincVimeoVideo(tag)) { 935 tag.addEventListener("load", function(evt) { 936 attachVimeoPlayerToTag(evt.currentTarget); 937 }); 938 } 939 } 940 } 941 942 }); 943 944 }, 945 946 manageCookies: function () { 947 948 try { 949 950 var expires = parseInt(options.cookie_duration); // days 951 952 var source = getTrafficSource(); 953 954 // manage traffic source cookie 955 if (source !== 'direct') { 956 Cookies.set('pysTrafficSource', source, { expires: expires }); 957 } else { 958 Cookies.remove('pysTrafficSource'); 959 } 960 961 var queryVars = getQueryVars(); 962 963 // manage utm cookies 964 $.each(utmTerms, function (index, name) { 965 966 if (Cookies.get('pys_' + name) === undefined && queryVars.hasOwnProperty(name)) { 967 Cookies.set('pys_' + name, queryVars[name], { expires: expires }); 968 } 969 970 }); 971 972 // manage landing cookies 973 if(Cookies.get('pys_landing_page') === undefined){ 974 var landing = window.location.href.split('?')[0]; 975 Cookies.set('pys_landing_page',landing,{ expires: expires }); 976 } 977 978 } catch (e) { 979 console.error(e); 980 } 981 982 }, 983
984 initializeRequestParams: function () { 985 986 if (options.trackTrafficSource) { 987 requestParams.traffic_source = getTrafficSource(); 988 } 989 990 if (options.trackUTMs) { 991 992 var utms = getUTMs(); 993 994 $.each(utmTerms, function (index, term) { 995 if (term in utms) { 996 requestParams[term] = utms[term]; 997 } 998 }); 999 1000 } 1001 1002 1003 var dateTime = getDateTime(); 1004 if(options.enable_event_time_param) { 1005 requestParams.event_time = dateTime[0]; 1006 } 1007 1008 if(options.enable_event_day_param) { 1009 requestParams.event_day = dateTime[1]; 1010 } 1011 if(options.enable_event_month_param) { 1012 requestParams.event_month = dateTime[2]; 1013 } 1014 1015 if(options.enable_lading_page_param){ 1016 requestParams.landing_page = getLandingPage(); 1017 } else { 1018 Cookies.remove('pys_landing_page'); 1019 } 1020 }, 1021
1022 getRequestParams: function () { 1023 return requestParams; 1024 }, 1025 1026 /** 1027 * DOWNLOAD DOCS 1028 */ 1029 1030 getLinkExtension: function (link) { 1031 1032 // Remove anchor, query string and everything before last slash 1033 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1034 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1035 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1036 1037 // If there's a period left in the URL, then there's a extension 1038 if (link.length > 0 && link.indexOf('.') !== -1) { 1039 link = link.substring(link.lastIndexOf(".") + 1); // Remove everything but what's after the first period 1040 return link; 1041 } else { 1042 return ""; 1043 } 1044 }, 1045 1046 getLinkFilename: function (link) { 1047 1048 // Remove anchor, query string and everything before last slash 1049 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1050 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1051 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1052 1053 // If there's a period left in the URL, then there's a extension 1054 if (link.length > 0 && link.indexOf('.') !== -1) { 1055 return link; 1056 } else { 1057 return ""; 1058 } 1059 }, 1060 1061 /** 1062 * CUSTOM EVENTS 1063 */ 1064 1065 setupMouseOverClickEvents: function (eventId, triggers) { 1066 1067 // Non-default binding used to avoid situations when some code in external js 1068 // stopping events propagation, eg. returns false, and our handler will never called 1069 $(document).onFirst('mouseover', triggers.join(','), function () { 1070 1071 // do not fire event multiple times 1072 if ($(this).hasClass('pys-mouse-over-' + eventId)) { 1073 return true; 1074 } else { 1075 $(this).addClass('pys-mouse-over-' + eventId); 1076 } 1077 1078 Utils.fireTriggerEvent(eventId); 1079 1080 }); 1081 1082 }, 1083 1084 setupCSSClickEvents: function (eventId, triggers) { 1085 1086 // Non-default binding used to avoid situations when some code in external js 1087 // stopping events propagation, eg. returns false, and our handler will never called 1088 // add event to document to support dyn class 1089 $(document).onFirst('click', triggers.join(','), function () { 1090 Utils.fireTriggerEvent(eventId); 1091 }); 1092 1093 }, 1094 1095 setupURLClickEvents: function () { 1096 1097 if( !options.triggerEventTypes.hasOwnProperty('url_click') ) { 1098 return; 1099 } 1100 // Non-default binding used to avoid situations when some code in external js 1101 // stopping events propagation, eg. returns false, and our handler will never called 1102 $('a').onFirst('click', function (evt) { 1103 1104 var url = $(this).attr('href'); 1105 if(url) { 1106 $.each(options.triggerEventTypes.url_click, function (eventId, triggers) { 1107 triggers.forEach(function (trigger) { 1108 if(Utils.compareUrl(url,trigger.value,trigger.rule)) { 1109 Utils.fireTriggerEvent(eventId); 1110 } 1111 }) 1112 }); 1113 } 1114 1115 }); 1116 1117 }, 1118 1119 removeUrlDomain(url) { 1120 if(url.indexOf("/#") > -1) { 1121 url = url.substring(0, url.indexOf("/#")); 1122 } 1123 return url.replace('http://','') 1124 .replace('https://','') 1125 .replace('www.','') 1126 .trim() 1127 .replace(/^\/+/g, '') 1128 1129 }, 1130 1131 compareUrl: function(base,url,rule){ 1132 1133 if(url == "*" || url == '') return true; 1134 1135 base = Utils.removeUrlDomain(base) 1136 url = Utils.removeUrlDomain(url) 1137 1138 if(rule == 'match') { 1139 return url == base; 1140 } else { 1141 return base.indexOf(url) > -1 1142 } 1143 1144 }, 1145 1146 setupScrollPosEvents: function (eventId, triggers) { 1147 1148 var scrollPosThresholds = {}, 1149 docHeight = $(document).height() - $(window).height(); 1150 1151 // convert % to absolute positions 1152 $.each(triggers, function (index, scrollPos) { 1153 1154 // convert % to pixels 1155 scrollPos = docHeight * scrollPos / 100; 1156 scrollPos = Math.round(scrollPos); 1157 1158 scrollPosThresholds[scrollPos] = eventId; 1159 1160 }); 1161 1162 $(document).on("scroll",function () { 1163 1164 var scrollPos = $(window).scrollTop(); 1165 1166 $.each(scrollPosThresholds, function (threshold, eventId) { 1167 1168 // position has not reached yes 1169 if (scrollPos <= threshold) { 1170 return true; 1171 } 1172 1173 // fire event only once 1174 if (eventId === null) { 1175 return true; 1176 } else { 1177 scrollPosThresholds[threshold] = null; 1178 } 1179 1180 Utils.fireTriggerEvent(eventId); 1181 1182 }); 1183 1184 }); 1185 1186 }, 1187 setupCommentEvents : function (eventId,triggers) { 1188 $('form.comment-form').on("submit",function () { 1189 Utils.fireTriggerEvent(eventId); 1190 }); 1191 }, 1192 /** 1193 * Events 1194 */ 1195 1196 isEventInTimeWindow: function (eventName, event, prefix) { 1197 1198 if(event.hasOwnProperty("hasTimeWindow") && event.hasTimeWindow) { 1199 var cookieName = prefix+"_"+eventName; 1200 var now = new Date().getTime(); 1201 1202 if(Cookies.get(cookieName) !== undefined) { 1203 1204 var lastTimeFire = Cookies.get(cookieName); 1205 var fireTime = event.timeWindow * 60*60*1000; 1206 1207 if( now - lastTimeFire > fireTime) { 1208 Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0} ); 1209 } else { 1210 return false;
1211 } 1212 } else { 1213 Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0} ); 1214 } 1215 } 1216 return true 1217 }, 1218 1219 fireTriggerEvent: function (eventId) { 1220 1221 if (!options.triggerEvents.hasOwnProperty(eventId)) { 1222 return; 1223 } 1224 1225 var event = {}; 1226 var events = options.triggerEvents[eventId]; 1227 1228 if (events.hasOwnProperty('facebook')) { 1229 event = events.facebook; 1230 if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) { 1231 Facebook.fireEvent(event.name, event); 1232 } 1233 } 1234 1235 if (events.hasOwnProperty('ga')) { 1236 event = events.ga; 1237 if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) { 1238 Analytics.fireEvent(event.name, event); 1239 } 1240 } 1241 1242 if (events.hasOwnProperty('google_ads')) { 1243 event = events.google_ads; 1244 if(Utils.isEventInTimeWindow(event.name,event,"dyn_google_ads_"+eventId)) { 1245 GAds.fireEvent(event.name, event); 1246 } 1247 } 1248 1249 if (events.hasOwnProperty('pinterest')) { 1250 event = events.pinterest; 1251 if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) { 1252 Pinterest.fireEvent(event.name, event);; 1253 } 1254 } 1255 1256 if (events.hasOwnProperty('bing')) { 1257 event = events.bing; 1258 if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) { 1259 Bing.fireEvent(event.name, event);; 1260 } 1261 } 1262 if (events.hasOwnProperty('tiktok')) { 1263 event = events.tiktok; 1264 if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) { 1265 TikTok.fireEvent(event.name, event); 1266 } 1267 } 1268 1269 1270 }, 1271 1272 isFirstPurchaseFire: function ($eventName,orderId,pixel) { 1273 1274 if(Cookies.get("pys_"+$eventName+"_order_id_"+pixel) == orderId) { 1275 return false; 1276 } else { 1277 Cookies.set("pys_"+$eventName+"_order_id_"+pixel, orderId, { expires: 1 }); 1278 } 1279 return true; 1280 }, 1281 1282 fireStaticEvents: function (pixel) { 1283 1284 if (options.staticEvents.hasOwnProperty(pixel)) { 1285 1286 $.each(options.staticEvents[pixel], function (eventId, events) { 1287 1288 //skip purchase event if this order was fired 1289 if( options.woo.hasOwnProperty('woo_purchase_on_transaction') && 1290 options.woo.woo_purchase_on_transaction && 1291 (eventId === "woo_purchase" || eventId === "woo_purchase_category") ) { 1292 if(!Utils.isFirstPurchaseFire(eventId,events[0].woo_order,pixel)) { 1293 return; 1294 } 1295 } 1296 1297 if( options.edd.hasOwnProperty('edd_purchase_on_transaction') && 1298 options.edd.edd_purchase_on_transaction && 1299 (eventId === "edd_purchase" || eventId === "edd_purchase_category") ) { 1300 if(!Utils.isFirstPurchaseFire(eventId,events[0].edd_order,pixel)) { 1301 return; 1302 } 1303 } 1304 1305 1306 $.each(events, function (index, event) { 1307 1308 event.fired = event.fired || false; 1309 1310 if (!event.fired && Utils.isEventInTimeWindow(event.name,event,'static_' + pixel+"_")) { 1311 1312 1313 var fired = false;
1314 1315 // fire event 1316 getPixelBySlag(pixel).fireEvent(event.name, event); 1317 1318 // prevent event double event firing 1319 event.fired = fired; 1320 } 1321 1322 }); 1323 }); 1324 1325 } 1326 }, 1327 1328 /** 1329 * Load tag's JS 1330 * 1331 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/ 1332 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 1333 */ 1334 loadGoogleTag: function (id) { 1335 1336 if (!gtag_loaded) { 1337 1338 (function (window, document, src) { 1339 var a = document.createElement('script'), 1340 m = document.getElementsByTagName('script')[0]; 1341 a.async = 1; 1342 a.src = src; 1343 m.parentNode.insertBefore(a, m); 1344 })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id); 1345 1346 window.dataLayer = window.dataLayer || []; 1347 window.gtag = window.gtag || function gtag() { 1348 dataLayer.push(arguments); 1349 }; 1350 1351 gtag('js', new Date()); 1352 1353 gtag_loaded = true; 1354 1355 } 1356 1357 }, 1358 1359 /** 1360 * GDPR 1361 */ 1362 1363 loadPixels: function () { 1364 1365 if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) { 1366 1367 // retrieves actual PYS GDPR filters values which allow to avoid cache issues 1368 $.get({ 1369 url: options.ajaxUrl, 1370 dataType: 'json', 1371 data: { 1372 action: 'pys_get_gdpr_filters_values' 1373 }, 1374 success: function (res) { 1375 1376 if (res.success) { 1377 1378 options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api; 1379 options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api; 1380 options.gdpr.tiktok_disabled_by_api = res.data.tiktok_disabled_by_api; 1381 options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api; 1382 options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api; 1383 options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api; 1384 options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api; 1385 1386 } 1387 1388 loadPixels(); 1389 1390 } 1391 }); 1392 1393 } else { 1394 loadPixels(); 1395 } 1396 1397 }, 1398 1399 consentGiven: function (pixel) { 1400 1401 /** 1402 * Cookiebot 1403 */ 1404 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1405 1406 var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category']; 1407 1408 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1409 if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) { 1410 return true; 1411 } 1412 } else { 1413 if (Cookiebot.consent[cookiebot_consent_category]) { 1414 return true; 1415 } 1416 } 1417 1418 return false; 1419 1420 } 1421 1422 /** 1423 * Cookie Notice 1424 */ 1425 if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') { 1426 1427 var cn_cookie = Cookies.get(cnArgs.cookieName); 1428 1429 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1430 if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') { 1431 return true; 1432 } 1433 } else { 1434 if (cn_cookie === 'true') { 1435 return true; 1436 } 1437 } 1438 1439 return false;
1440 1441 } 1442 1443 /** 1444 * Cookie Law Info 1445 */ 1446 if (options.gdpr.cookie_law_info_integration_enabled) { 1447 1448 var cli_cookie = Cookies.get('viewed_cookie_policy'); 1449 1450 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1451 if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') { 1452 return true; 1453 } 1454 } else { 1455 if (cli_cookie === 'yes') { 1456 return true; 1457 } 1458 } 1459 1460 return false; 1461 1462 } 1463 1464 /** 1465 * ConsentMagic 1466 */ 1467 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 1468 1469 var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix); 1470 1471 if (options.gdpr[pixel + '_prior_consent_enabled']) { 1472 if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') { 1473 return true; 1474 } 1475 } else { 1476 if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') { 1477 return true; 1478 } 1479 } 1480 1481 return false; 1482 1483 } 1484 1485 1486 /** 1487 * Real Cookie Banner 1488 */ 1489 if (options.gdpr.real_cookie_banner_integration_enabled) { 1490 var consentApi = window.consentApi; 1491 if (consentApi) { 1492 switch (pixel) { 1493 case "analytics": 1494 return consentApi.consentSync("http", "_ga", "*").cookieOptIn; 1495 case "facebook": 1496 return consentApi.consentSync("http", "_fbp", "*").cookieOptIn; 1497 case "pinterest": 1498 return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn; 1499 case "bing": 1500 return consentApi.consentSync("http", "_uetsid", "*").cookieOptIn; 1501 case "google_ads": 1502 return consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn; 1503 case 'tiktok': 1504 return consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn; 1505 default: 1506 return true; 1507 } 1508 } 1509 } 1510 1511 return true; 1512 1513 }, 1514 1515 setupGdprCallbacks: function () { 1516 1517 /** 1518 * Cookiebot 1519 */ 1520 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1521 1522 window.addEventListener("CookiebotOnConsentReady", function() { 1523 if (Cookiebot.consent.marketing) { 1524 Facebook.loadPixel(); 1525 Bing.loadPixel(); 1526 Pinterest.loadPixel(); 1527 GAds.loadPixel(); 1528 TikTok.loadPixel(); 1529 } 1530 if (Cookiebot.consent.statistics) { 1531 Analytics.loadPixel(); 1532 } 1533 if (!Cookiebot.consent.marketing) { 1534 Facebook.disable(); 1535 Pinterest.disable(); 1536 Bing.disable() 1537 GAds.disable(); 1538 TikTok.disable(); 1539 } 1540 if (!Cookiebot.consent.statistics) { 1541 Analytics.disable(); 1542 } 1543 }); 1544 } 1545 1546 /** 1547 * Cookie Notice 1548 */ 1549 if (options.gdpr.cookie_notice_integration_enabled) { 1550 1551 $(document).onFirst('click', '.cn-set-cookie', function () { 1552 1553 if ($(this).data('cookie-set') === 'accept') { 1554 Facebook.loadPixel(); 1555 Analytics.loadPixel(); 1556 GAds.loadPixel(); 1557 Pinterest.loadPixel(); 1558 Bing.loadPixel(); 1559 TikTok.loadPixel(); 1560 } else { 1561 Facebook.disable(); 1562 Analytics.disable(); 1563 GAds.disable(); 1564 Pinterest.disable(); 1565 Bing.disable(); 1566 TikTok.disable(); 1567 } 1568 1569 }); 1570 1571 $(document).onFirst('click', '.cn-revoke-cookie', function () { 1572 Facebook.disable(); 1573 Analytics.disable(); 1574 GAds.disable(); 1575 Pinterest.disable(); 1576 Bing.disable(); 1577 TikTok.disable(); 1578 }); 1579 1580 } 1581 1582 /** 1583 * Cookie Law Info 1584 */ 1585 if (options.gdpr.cookie_law_info_integration_enabled) { 1586 1587 $(document).onFirst('click', '#cookie_action_close_header', function () { 1588 Facebook.loadPixel(); 1589 Analytics.loadPixel(); 1590 GAds.loadPixel(); 1591 Pinterest.loadPixel(); 1592 Bing.loadPixel(); 1593 TikTok.loadPixel(); 1594 }); 1595 1596 $(document).onFirst('click', '#cookie_action_close_header_reject', function () { 1597 Facebook.disable(); 1598 Analytics.disable(); 1599 GAds.disable(); 1600 Pinterest.disable(); 1601 Bing.disable(); 1602 TikTok.disable(); 1603 }); 1604 1605 } 1606 1607 /** 1608 * ConsentMagic 1609 */ 1610 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 1611 var test_prefix = CS_Data.test_prefix, 1612 cs_refresh_after_consent = false, 1613 substring = "cs_enabled_cookie_term"; 1614 1615 if (CS_Data.cs_refresh_after_consent == 1) { 1616 cs_refresh_after_consent = CS_Data.cs_refresh_after_consent; 1617 } 1618 1619 if (!cs_refresh_after_consent) { 1620 var theCookies = document.cookie.split(';'); 1621 for (var i = 1 ; i <= theCookies.length; i++) { 1622 if (theCookies[i-1].indexOf(substring) !== -1) { 1623 var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_',''); 1624 categoryCookie = Number(categoryCookie.replace(/\D+/g,"")); 1625 var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie); 1626 if(cs_cookie_val == 'yes') { 1627 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 1628 Facebook.loadPixel(); 1629 } 1630 1631 if (categoryCookie === CS_Data.cs_script_cat.bing) { 1632 Bing.loadPixel(); 1633 } 1634 1635 if (categoryCookie === CS_Data.cs_script_cat.analytics) { 1636 Analytics.loadPixel(); 1637 } 1638 1639 if (categoryCookie === CS_Data.cs_script_cat.gads) { 1640 GAds.loadPixel(); 1641 } 1642 1643 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 1644 Pinterest.loadPixel(); 1645 } 1646 1647 if (categoryCookie === CS_Data.cs_script_cat.tiktok) { 1648 TikTok.loadPixel(); 1649 } 1650 } else { 1651 if (categoryCookie === CS_Data.cs_script_cat.facebook) { 1652 Facebook.disable(); 1653 } 1654 1655 if (categoryCookie === CS_Data.cs_script_cat.bing) { 1656 Bing.disable(); 1657 } 1658 1659 if (categoryCookie === CS_Data.cs_script_cat.analytics) { 1660 Analytics.disable(); 1661 } 1662 1663 if (categoryCookie === CS_Data.cs_script_cat.gads) { 1664 GAds.disable(); 1665 } 1666 1667 if (categoryCookie === CS_Data.cs_script_cat.pinterest) { 1668 Pinterest.disable(); 1669 } 1670 1671 if (categoryCookie === CS_Data.cs_script_cat.tiktok) { 1672 TikTok.disable(); 1673 } 1674 } 1675 if (Cookies.get('cs_enabled_advanced_matching') == 'yes') { 1676 Facebook.loadPixel(); 1677 } 1678 } 1679 } 1680 1681 $(document).on('click','.cs_action_btn',function(e) { 1682 e.preventDefault(); 1683 var elm = $(this), 1684 button_action = elm.attr('data-cs_action'); 1685 1686 if(button_action === 'allow_all') { 1687 Facebook.loadPixel(); 1688 Bing.loadPixel(); 1689 Analytics.loadPixel(); 1690 GAds.loadPixel(); 1691 Pinterest.loadPixel(); 1692 TikTok.loadPixel(); 1693 } else if(button_action === 'disable_all') { 1694 Facebook.disable(); 1695 Bing.disable(); 1696 Analytics.disable(); 1697 GAds.disable(); 1698 Pinterest.disable(); 1699 TikTok.disable(); 1700 } 1701 }); 1702 } 1703 } 1704 1705 /** 1706 * Real Cookie Banner 1707 */ 1708 if (options.gdpr.real_cookie_banner_integration_enabled) { 1709 var consentApi = window.consentApi; 1710 if (consentApi) { 1711 consentApi.consent("http", "_ga", "*") 1712 .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics)); 1713 1714 consentApi.consent("http", "_fbp", "*") 1715 .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook)); 1716 1717 consentApi.consent("http", "_pinterest_sess", ".pinterest.com") 1718 .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest)); 1719 1720 consentApi.consent("http", "_uetsid", "*") 1721 .then(Bing.loadPixel.bind(Bing), Bing.disable.bind(Bing)); 1722 1723 consentApi.consent("http", "1P_JAR", ".google.com") 1724 .then(GAds.loadPixel.bind(GAds), GAds.disable.bind(GAds)); 1725 consentApi.consent("http", "tt_webid_v2", ".tiktok.com") 1726 .then(TikTok.loadPixel.bind(GAds), TikTok.disable.bind(GAds)); 1727 } 1728 } 1729 1730 }, 1731 1732 /** 1733 * Enrich 1734 */ 1735 isCheckoutPage: function () { 1736 return $('body').hasClass('woocommerce-checkout') || 1737 $('body').hasClass('edd-checkout'); 1738 }, 1739 addCheckoutFields : function() { 1740 1741 var utm = ""; 1742 var utms = getUTMs() 1743 $.each(utmTerms, function (index, name) { 1744 if(index > 0) { 1745 utm+="|"; 1746 } 1747 utm+=name+":"+utms[name]; 1748 }); 1749 var dateTime = getDateTime(); 1750 var landing = Cookies.get('pys_landing_page'); 1751 1752 var $form = null; 1753 if($('body').hasClass('woocommerce-checkout')) { 1754 $form = $("form.woocommerce-checkout"); 1755 } else { 1756 $form = $("#edd_purchase_form"); 1757 } 1758 var inputs = {'pys_utm':utm, 1759 'pys_browser_time':dateTime.join("|"), 1760 'pys_landing':landing, 1761 'pys_source':getTrafficSource(), 1762 'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal" 1763 } 1764
1765 Object.keys(inputs).forEach(function(key,index) { 1766 $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> "); 1767 }); 1768 1769 1770 } 1771 }; 1772 1773 }(options); 1774 1775 var TikTok = function (options) { 1776 1777 var initialized = false; 1778 1779 function fireEvent(name, event) { 1780 1781 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'tiktok')) { 1782 return; 1783 } 1784 var params = Utils.copyProperties(event.params, {}); 1785 1786 event.pixelIds.forEach(function(pixelId){ 1787 if (options.debug) { 1788 console.log('[TikTok] ' + name, params,"pixel_id",pixelId); 1789 } 1790 1791 if(options.tiktok.hasOwnProperty('advanced_matching') 1792 && Object.keys(options.tiktok.advanced_matching).length > 0) { 1793 ttq.instance(pixelId).identify(options.tiktok.advanced_matching) 1794 } 1795 1796 ttq.instance(pixelId).track(name,params) 1797 }); 1798 1799 } 1800 1801 return { 1802 tag: function() { 1803 return "tiktok"; 1804 }, 1805 isEnabled: function () { 1806 return options.hasOwnProperty('tiktok'); 1807 }, 1808 disable: function () { 1809 initialized = false; 1810 }, 1811 1812 loadPixel:function () { 1813 if (initialized || !this.isEnabled() || !Utils.consentGiven('tiktok')) { 1814 return; 1815 } 1816 1817 !function (w, d, t) { 1818 w.TiktokAnalyticsObject=t; 1819 var ttq=w[t]=w[t]||[]; 1820 ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"]; 1821 ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}; 1822 for(var i=0;i<ttq.methods.length;i++) 1823 ttq.setAndDefer(ttq,ttq.methods[i]); 1824 ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e}; 1825 ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)}; 1826 1827 //ttq.load('C60QSCQRVDG9JAKNPK2G'); 1828 //ttq.page(); 1829 }(window, document, 'ttq'); 1830 1831 options.tiktok.pixelIds.forEach(function (pixelId) { 1832 ttq.load(pixelId); 1833 ttq.page(); 1834 }); 1835 initialized = true; 1836 Utils.fireStaticEvents('tiktok'); 1837 }, 1838 1839 fireEvent: function (name, data) { 1840 if (!initialized || !this.isEnabled()) { 1841 return false; 1842 } 1843 data.delay = data.delay || 0; 1844 1845 if (data.delay === 0) { 1846 fireEvent(name, data); 1847 } else { 1848 setTimeout(function (name, params) { 1849 fireEvent(name, params); 1850 }, data.delay * 1000, name, data); 1851 } 1852 return true; 1853 }, 1854 1855 onClickEvent: function (event) { 1856 this.fireEvent(event.name, event); 1857 }, 1858 1859 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 1860 1861 window.pysWooProductData = window.pysWooProductData || []; 1862 if (!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1863 return; 1864 1865 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1866 if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) { 1867 1868 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 1869 1870 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()]['params'], event.params); 1871 1872 // maybe customize value option 1873 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 1874 1875 if (product_type === Utils.PRODUCT_BUNDLE) { 1876 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 1877 var items_sum = getBundlePriceOnSingleProduct(data); 1878 event.params.value = (parseFloat(data.base_price) + items_sum) * qty; 1879 } else { 1880 event.params.value = event.params.value * qty; 1881 } 1882 } 1883 1884 event.params.quantity = qty; 1885 1886 this.fireEvent(event.name, event); 1887 1888 } 1889 } 1890 }, 1891 1892 onWooAddToCartOnButtonEvent: function (product_id) { 1893 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1894 return; 1895 1896 if (window.pysWooProductData.hasOwnProperty(product_id)) { 1897 if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) { 1898 var productData = window.pysWooProductData[product_id][this.tag()] 1899 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 1900 1901 Utils.copyProperties(productData['params'], event.params) 1902 event.pixelIds = productData['pixelIds']; 1903 this.fireEvent(event.name, event); 1904 } 1905 } 1906 }, 1907 1908 onEddAddToCartOnButtonEvent : function (download_id, price_index, qty) { 1909 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 1910 return; 1911 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 1912 1913 1914 if (window.pysEddProductData.hasOwnProperty(download_id)) { 1915 1916 var index; 1917 1918 if (price_index) { 1919 index = download_id + '_' + price_index; 1920 } else { 1921 index = download_id; 1922 } 1923 1924 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 1925 if (window.pysEddProductData[download_id][index].hasOwnProperty(this.tag())) { 1926 1927 Utils.copyProperties(window.pysEddProductData[download_id][index][this.tag()].params, event.params); 1928 this.fireEvent(event.name,event); 1929 1930 } 1931 } 1932 1933 } 1934 } 1935 } 1936 }(options); 1937 1938 var Facebook = function (options) { 1939 1940 var defaultEventTypes = [ 1941 'PageView', 1942 'ViewContent', 1943 'Search', 1944 'AddToCart', 1945 'AddToWishlist', 1946 'InitiateCheckout', 1947 'AddPaymentInfo', 1948 'Purchase', 1949 'Lead', 1950 1951 'Subscribe', 1952 'CustomizeProduct', 1953 'FindLocation', 1954 'StartTrial', 1955 'SubmitApplication', 1956 'Schedule', 1957 'Contact', 1958 'Donate' 1959 ]; 1960 1961 var notCachedEventsIds = new Array(); 1962 var isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod") 1963 && options.woo.addToCartCatchMethod === "add_cart_js"; 1964 if(!isAddToCartFromJs) { 1965 notCachedEventsIds.push('woo_add_to_cart_on_button_click') 1966 } 1967 var initialized = false;
1968 var configuredPixels = new Array(); 1969 function fireEvent(name, event) { 1970 1971 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) { 1972 return; 1973 } 1974 1975 var data = event.params; 1976 var ids = event.pixelIds; 1977 var actionType = defaultEventTypes.includes(name) ? 'trackSingle' : 'trackSingleCustom'; 1978 1979 var params = {}; 1980 1981 Utils.copyProperties(data, params); 1982 Utils.copyProperties(Utils.getRequestParams(), params); 1983 1984 1985 if(options.facebook.serverApiEnabled) { 1986 if(event.e_id === "woo_remove_from_cart" ) { 1987 Facebook.updateEventId(event.name); 1988 event.eventID = Facebook.getEventId(event.name); 1989 } else if(isAddToCartFromJs && event.e_id === "woo_add_to_cart_on_button_click" ) { 1990 Facebook.updateEventId(event.name); 1991 event.eventID = Facebook.getEventId(event.name); 1992 } else if(!notCachedEventsIds.includes(event.e_id)) { 1993 var isApiDisabled = options.gdpr.all_disabled_by_api || 1994 options.gdpr.facebook_disabled_by_api || 1995 options.gdpr.tiktok_disabled_by_api || 1996 options.gdpr.cookiebot_integration_enabled || 1997 options.gdpr.cookie_notice_integration_enabled || 1998 options.gdpr.consent_magic_integration_enabled || 1999 options.gdpr.cookie_law_info_integration_enabled; 2000 // Update eventID 2001 if( options.facebook.ajaxForServerEvent || event.type !== "static") { 2002 event.eventID = pys_generate_token(36); 2003 } 2004 2005 // send event from server if they was bloc by gdpr or need send with delay 2006 if( options.facebook.ajaxForServerEvent || isApiDisabled || event.delay > 0 || event.type !== "static" ){ 2007 2008 var json = { 2009 action: 'pys_api_event', 2010 pixel: 'facebook', 2011 event: name, 2012 ids: ids, 2013 data:params, 2014 url:window.location.href, 2015 eventID:event.eventID, 2016 }; 2017 2018 if(event.hasOwnProperty('woo_order')) { 2019 json['woo_order'] = event.woo_order; 2020 } 2021 2022 if(event.hasOwnProperty('edd_order')) { 2023 json['edd_order'] = event.edd_order; 2024 } 2025 2026 if(event.e_id === "automatic_event_internal_link" 2027 || event.e_id === "automatic_event_outbound_link" 2028 ) { 2029 setTimeout(function(){ 2030 jQuery.ajax( { 2031 type: 'POST', 2032 url: options.ajaxUrl, 2033 data: json, 2034 headers: { 2035 'Cache-Control': 'no-cache' 2036 }, 2037 success: function(){}, 2038 }); 2039 },500) 2040 } else { 2041 jQuery.ajax( { 2042 type: 'POST', 2043 url: options.ajaxUrl, 2044 data: json, 2045 headers: { 2046 'Cache-Control': 'no-cache' 2047 }, 2048 success: function(){}, 2049 }); 2050 } 2051 2052 2053 } 2054 2055 if( event.e_id !== "automatic_event_signup" && name == "CompleteRegistration" && options.facebook.wooCRSendFromServer ) { 2056 return; 2057 } 2058 } 2059 2060 } 2061 2062 2063 2064 if (options.debug) { 2065 console.log('[Facebook] ' + name, params,"pixel_ids",ids,"eventID",event.eventID); 2066 } 2067 // fire event for each pixel id 2068 ids.forEach(function (pixelId) { 2069 // add eventID for deduplicate events @see https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events/ 2070 var args = {}; 2071 if(options.facebook.serverApiEnabled && event.hasOwnProperty('eventID')) { 2072 args.eventID = pixelId+event.eventID; 2073 } 2074 2075 Facebook.maybeInitPixel(pixelId); 2076 fbq(actionType,pixelId, name, params,args); 2077 }); 2078 2079 } 2080 2081 /** 2082 * Public API 2083 */ 2084 return { 2085 tag: function() { 2086 return "facebook"; 2087 }, 2088 isEnabled: function () { 2089 return options.hasOwnProperty('facebook'); 2090 }, 2091
2092 initEventIdCookies: function (key) { 2093 var ids = {}; 2094 ids[key] = pys_generate_token(36) 2095 Cookies.set('pys_fb_event_id', JSON.stringify(ids)); 2096 }, 2097 2098 updateEventId:function(key) { 2099 var cooData = Cookies.get("pys_fb_event_id") 2100 if(data === undefined) { 2101 this.initEventIdCookies(key); 2102 } else { 2103 var data = JSON.parse(cooData); 2104 data[key] = pys_generate_token(36); 2105 Cookies.set('pys_fb_event_id', JSON.stringify(data) ); 2106 } 2107 }, 2108 2109 getEventId:function (key) { 2110 var data = Cookies.get("pys_fb_event_id"); 2111 if(data === undefined) { 2112 this.initEventIdCookies(key); 2113 data = Cookies.get("pys_fb_event_id"); 2114 } 2115 return JSON.parse(data)[key]; 2116 }, 2117 2118 disable: function () { 2119 initialized = false; 2120 }, 2121 2122 /** 2123 * Load pixel's JS 2124 */ 2125 loadPixel: function () { 2126 2127 if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) { 2128 return; 2129 } 2130 2131 ! function (f, b, e, v, n, t, s) { 2132 if (f.fbq) return; 2133 n = f.fbq = function () { 2134 n.callMethod ? 2135 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 2136 }; 2137 if (!f._fbq) f._fbq = n; 2138 n.push = n; 2139 n.loaded = !0; 2140 n.version = '2.0'; 2141 n.agent = 'dvpixelyoursite'; 2142 n.queue = []; 2143 t = b.createElement(e); 2144 t.async = !0; 2145 t.src = v; 2146 s = b.getElementsByTagName(e)[0]; 2147 s.parentNode.insertBefore(t, s) 2148 }(window, 2149 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 2150 2151 // initialize default pixel 2152 options.facebook.pixelIds.forEach(function (pixelId) { 2153 Facebook.maybeInitPixel(pixelId); 2154 }); 2155 initialized = true; 2156 2157 Utils.fireStaticEvents('facebook'); 2158 2159 }, 2160 maybeInitPixel: function(pixelId) { 2161 2162 if(configuredPixels.includes(pixelId)) return; 2163 2164 if (options.facebook.removeMetadata) { 2165 fbq('set', 'autoConfig', false, pixelId); 2166 } 2167 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 2168 if(options.facebook.advancedMatching.length === 0) { 2169 fbq('init', pixelId); 2170 } else { 2171 var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix); 2172 if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) { 2173 if (cs_advanced_matching == 'yes') { 2174 fbq('init', pixelId, options.facebook.advancedMatching); 2175 } else { 2176 fbq('init', pixelId); 2177 } 2178 } else { 2179 fbq('init', pixelId, options.facebook.advancedMatching); 2180 } 2181 } 2182 } else { 2183 if(options.facebook.advancedMatching.length === 0) { 2184 fbq('init', pixelId); 2185 } else { 2186 fbq('init', pixelId, options.facebook.advancedMatching); 2187 } 2188 } 2189 configuredPixels.push(pixelId); 2190 }, 2191 2192 fireEvent: function (name, data) { 2193 2194 if (!initialized || !this.isEnabled()) { 2195 return false; 2196 } 2197 2198 data.delay = data.delay || 0; 2199 data.params = data.params || {}; 2200 2201 if (data.delay === 0) { 2202 2203 fireEvent(name, data); 2204 2205 } else { 2206 2207 setTimeout(function (name, params) { 2208 fireEvent(name, params); 2209 }, data.delay * 1000, name, data); 2210 2211 } 2212 2213 return true; 2214 2215 }, 2216 2217 onAdSenseEvent: function (event) { 2218 this.fireEvent(event.name, event); 2219 }, 2220 2221 onClickEvent: function (event) { 2222 this.fireEvent(event.name, event); 2223 }, 2224 2225 onWatchVideo: function (event) { 2226 this.fireEvent(event.name, event); 2227 }, 2228 2229 onCommentEvent: function (event) { 2230 this.fireEvent(event.name, event); 2231 }, 2232 2233 onFormEvent: function (event) { 2234 this.fireEvent(event.name, event); 2235 }, 2236 2237 onDownloadEvent: function (event) { 2238 this.fireEvent(event.name, event); 2239 2240 }, 2241 2242 2243 onWooAddToCartOnButtonEvent: function (product_id) { 2244 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2245 return; 2246 2247 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2248 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 2249 2250 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 2251 2252 Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params) 2253 event.pixelIds = window.pysWooProductData[product_id]['facebook']['pixelIds']; 2254 this.fireEvent(event.name, event); 2255 } 2256 } 2257 }, 2258 2259 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 2260 2261 window.pysWooProductData = window.pysWooProductData || []; 2262 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2263 return; 2264 2265 if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) { 2266 product_id = parseInt($form.find('input[name="variation_id"]').val()); 2267 } 2268 2269 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2270 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 2271 2272 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click.facebook); 2273 2274 2275 Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params); 2276 2277 var groupValue = 0; 2278 if(product_type === Utils.PRODUCT_GROUPED ) { 2279 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 2280 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 2281 var quantity = parseInt($(this).val()); 2282 if(isNaN(quantity)) { 2283 quantity = 0; 2284 } 2285 var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId]; 2286 2287 if(quantity == 0) { 2288 event.params.content_ids.forEach(function(el,index,array) { 2289 if(el == childItem.content_id) { 2290 array.splice(index, 1); 2291 } 2292 }); 2293 } 2294 2295 if(event.params.hasOwnProperty('contents')) { 2296 event.params.contents.forEac
2296h(function(el,index,array) { 2297 if(el.id == childItem.content_id) { 2298 if(quantity > 0){ 2299 el.quantity = quantity; 2300 } else { 2301 array.splice(index, 1); 2302 } 2303 } 2304 }); 2305 } 2306 2307 2308 groupValue += childItem.price * quantity; 2309 }); 2310 if(groupValue == 0) return; // skip if no items selected 2311 } 2312 2313 2314 2315 // maybe customize value option 2316 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 2317 2318 if(product_type === Utils.PRODUCT_GROUPED) { 2319 event.params.value = groupValue; 2320 } else if(product_type === Utils.PRODUCT_BUNDLE) { 2321 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 2322 var items_sum = getBundlePriceOnSingleProduct(data); 2323 event.params.value = (parseFloat(data.base_price) + items_sum )* qty; 2324 } else { 2325 event.params.value = event.params.value * qty; 2326 } 2327 } 2328 2329 // only when non Facebook for WooCommerce logic used 2330 if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) { 2331 event.params.contents[0].quantity = qty; 2332 2333 } 2334 2335 var event_name = is_external ? options.woo.affiliateEventName : event.name; 2336 2337 this.fireEvent(event_name, event); 2338 2339 } 2340 } 2341 2342 }, 2343 2344 onWooRemoveFromCartEvent: function (event) { 2345 this.fireEvent(event.name, event); 2346 }, 2347 2348 onWooAffiliateEvent: function (product_id) { 2349 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 2350 return; 2351 var event = Utils.clone(options.dynamicEvents.woo_affiliate[this.tag()]); 2352 2353 2354 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2355 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 2356 2357 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()].params, event.params) 2358 this.fireEvent(options.woo.affiliateEventName, event); 2359 2360 } 2361 } 2362 2363 }, 2364 2365 onWooPayPalEvent: function (event) { 2366 this.fireEvent(event.name, event); 2367 }, 2368 2369 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 2370 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2371 return; 2372 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 2373 2374 if (window.pysEddProductData.hasOwnProperty(download_id)) { 2375 2376 var index; 2377 2378 if (price_index) { 2379 index = download_id + '_' + price_index; 2380 } else { 2381 index = download_id; 2382 } 2383 2384 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 2385 if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) { 2386 2387 2388 Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params) 2389 2390 // maybe customize value option 2391 if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') { 2392 event.params.value = event.params.value * qty; 2393 } 2394 2395 // update contents qty param 2396 var contents = event.params.contents; 2397 contents[0].quantity = qty; 2398 event.params.contents = JSON.stringify(contents); 2399 2400 this.fireEvent(event.name,event); 2401 2402 } 2403 } 2404 2405 } 2406 2407 }, 2408 2409 onEddRemoveFromCartEvent: function (event) { 2410 this.fireEvent(event.name, event); 2411 }, 2412 onPageScroll: function (event) { 2413 this.fireEvent(event.name, event); 2414 }, 2415 onTime: function (event) { 2416 this.fireEvent(event.name, event); 2417 }, 2418 }; 2419 2420 }(options); 2421 2422 var Analytics = function (options) { 2423 2424 var initialized = false;
2425 2426 /** 2427 * Fires event 2428 * 2429 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 2430 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 2431 * @link: https://developers.google.com/gtagjs/reference/event 2432 * @link: https://developers.google.com/gtagjs/reference/parameter 2433 * 2434 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets 2435 * 2436 * @param name 2437 * @param data 2438 */ 2439 function fireEvent(name, data) { 2440 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) { 2441 return; 2442 } 2443 2444 var eventParams = Utils.copyProperties(data.params, {}); 2445 Utils.copyProperties(Utils.getRequestParams(), eventParams); 2446 2447 var _fireEvent = function (tracking_id,name,params) { 2448 2449 params['send_to'] = tracking_id; 2450 if (options.debug) { 2451 console.log('[Google Analytics #' + tracking_id + '] ' + name, params); 2452 } 2453 2454 gtag('event', name, params); 2455 2456 }; 2457 2458 data.trackingIds.forEach(function (tracking_id) { 2459 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it 2460 var params = mapParamsTov4(tracking_id,name,copyParams) 2461 _fireEvent(tracking_id, name, params); 2462 }); 2463 2464 } 2465 2466 function normalizeEventName(eventName) { 2467 2468 var matches = { 2469 ViewContent: 'view_item', 2470 AddToCart: 'add_to_cart', 2471 AddToWishList: 'add_to_wishlist', 2472 InitiateCheckout: 'begin_checkout', 2473 Purchase: 'purchase', 2474 Lead: 'generate_lead', 2475 CompleteRegistration: 'sign_up', 2476 AddPaymentInfo: 'set_checkout_option' 2477 }; 2478 2479 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 2480 2481 } 2482 2483 function mapParamsTov4(tag,name,param) { 2484 //GA4 automatically collects a number of parameters for all events 2485 delete param.page_title; 2486 delete param.event_url; 2487 delete param.landing_page; 2488 // end 2489 if(isv4(tag)) { 2490 delete param.traffic_source; 2491 delete param.event_category; 2492 delete param.event_label; 2493 delete param.ecomm_prodid; 2494 delete param.ecomm_pagetype; 2495 delete param.ecomm_totalvalue; 2496 if(name === 'search') { 2497 param['search'] = param.search_term; 2498 delete param.search_term; 2499 delete param.non_interaction; 2500 delete param.dynx_itemid; 2501 delete param.dynx_pagetype; 2502 delete param.dynx_totalvalue; 2503 } 2504 } else { 2505 2506 switch (name) { 2507 case 'OutboundClick': 2508 case 'InternalClick': { 2509 let params = { 2510 event_category: "Key Actions", 2511 event_action: name, 2512 non_interaction: param.non_interaction, 2513 } 2514 if(param.hasOwnProperty("target_url")) { 2515 params['event_label'] = param.target_url 2516 } 2517 if(options.trackTrafficSource) { 2518 params['traffic_source'] = param.traffic_source 2519 } 2520 return params; 2521 } 2522 2523 case 'AdSense' : 2524 case 'Comment' : 2525 case 'login' : 2526 case 'sign_up' : 2527 case 'EmailClick' : 2528 case 'TelClick' : { 2529 let params = { 2530 event_category: "Key Actions", 2531 event_action: name,
2532 non_interaction: param.non_interaction, 2533 } 2534 return params; 2535 } 2536 case 'Form' : { 2537 let params = { 2538 event_category: "Key Actions", 2539 event_action: name, 2540 non_interaction: param.non_interaction, 2541 } 2542 var formClass = (typeof param.form_class != 'undefined') ? 'class: ' + param.form_class : ''; 2543 if(formClass != "") { 2544 params["event_label"] = formClass; 2545 } 2546 return params; 2547 } 2548 case 'Download' : { 2549 let params = { 2550 event_category: "Key Actions", 2551 event_action: name, 2552 event_label: param.download_name, 2553 non_interaction: param.non_interaction, 2554 } 2555 return params; 2556 } 2557 case 'TimeOnPage' : 2558 case 'PageScroll' : { 2559 let params = { 2560 event_category: "Key Actions", 2561 event_action: name, 2562 event_label: document.title, 2563 non_interaction: param.non_interaction, 2564 } 2565 return params; 2566 } 2567 case 'search' : { 2568 let params = { 2569 event_category: "Key Actions", 2570 event_action: name, 2571 event_label: param.search_term, 2572 non_interaction: param.non_interaction, 2573 } 2574 return params; 2575 } 2576 } 2577 2578 //delete standard params 2579 2580 delete param.post_type; 2581 delete param.post_id; 2582 delete param.plugin; 2583 delete param.user_role; 2584 delete param.cartlows; 2585 delete param.cartflows_flow; 2586 delete param.cartflows_step; 2587 } 2588 return param; 2589 } 2590 2591 function isv4(tag) { 2592 return tag.indexOf('G') === 0; 2593 } 2594 2595 /** 2596 * Public API 2597 */ 2598 return { 2599 tag: function() { 2600 return "ga"; 2601 }, 2602 isEnabled: function () { 2603 return options.hasOwnProperty('ga'); 2604 }, 2605 2606 disable: function () { 2607 initialized = false; 2608 }, 2609 2610 loadPixel: function () { 2611 2612 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 2613 return; 2614 } 2615 2616 Utils.loadGoogleTag(options.ga.trackingIds[0]); 2617 2618 var cd = { 2619 'dimension1': 'event_hour', 2620 'dimension2': 'event_day', 2621 'dimension3': 'event_month' 2622 }; 2623 2624 // configure Dynamic Remarketing CDs 2625 if (options.ga.retargetingLogic === 'ecomm') { 2626 cd.dimension4 = 'ecomm_prodid'; 2627 cd.dimension5 = 'ecomm_pagetype'; 2628 cd.dimension6 = 'ecomm_totalvalue'; 2629 } else { 2630 cd.dimension4 = 'dynx_itemid'; 2631 cd.dimension5 = 'dynx_pagetype'; 2632 cd.dimension6 = 'dynx_totalvalue'; 2633 } 2634 2635 var config = { 2636 'link_attribution': options.ga.enhanceLinkAttr, 2637 'anonymize_ip': options.ga.anonimizeIP, 2638 'custom_map': cd 2639 }; 2640 2641 if(options.user_id && options.user_id != 0) { 2642 config.user_id = options.user_id; 2643 } 2644 2645 // Cross-Domain tracking 2646 if (options.ga.crossDomainEnabled) { 2647 config.linker = { 2648 accept_incoming: options.ga.crossDomainAcceptIncoming, 2649 domains: options.ga.crossDomainDomains 2650 }; 2651 } 2652 2653 2654 2655 // configure tracking ids 2656 2657 options.ga.trackingIds.forEach(function (trackingId,index) { 2658 if(options.ga.isDebugEnabled.includes("index_"+index)) { 2659 config.debug_mode = true; 2660 } else { 2661 config.debug_mode = false;
2662 } 2663 if(isv4(trackingId)) { 2664 if(options.ga.disableAdvertisingFeatures) { 2665 config.allow_google_signals = false 2666 } 2667 if(options.ga.disableAdvertisingPersonalization) { 2668 config.allow_ad_personalization_signals = false 2669 } 2670 } 2671 2672 gtag('config', trackingId, config); 2673 2674 }); 2675 2676 initialized = true; 2677 2678 Utils.fireStaticEvents('ga'); 2679 $( document).trigger( "analytics_initialized") 2680 }, 2681 2682 fireEvent: function (name, data) { 2683 2684 if (!initialized || !this.isEnabled()) { 2685 return false; 2686 } 2687 2688 data.delay = data.delay || 0; 2689 data.params = data.params || {}; 2690 2691 if (data.delay === 0) { 2692 2693 fireEvent(name, data); 2694 2695 } else { 2696 2697 setTimeout(function (name, params) { 2698 fireEvent(name, params); 2699 }, data.delay * 1000, name, data); 2700 2701 } 2702 2703 return true; 2704 2705 }, 2706 2707 onAdSenseEvent: function () { 2708 // not supported 2709 }, 2710 2711 onClickEvent: function (event) { 2712 this.fireEvent(event.name, event); 2713 }, 2714 2715 onWatchVideo: function (event) { 2716 if(!event.hasOwnProperty("youtube_disabled") 2717 || !event.youtube_disabled 2718 || event.params.video_type !== "youtube") { 2719 this.fireEvent(event.name, event); 2720 } 2721 }, 2722 2723 onCommentEvent: function (event) { 2724 2725 this.fireEvent(event.name, event); 2726 2727 }, 2728 2729 onFormEvent: function (event) { 2730 2731 this.fireEvent(event.name, event); 2732 2733 }, 2734 2735 onDownloadEvent: function (event) { 2736 2737 this.fireEvent(event.name, event); 2738 2739 }, 2740 2741 onWooAddToCartOnButtonEvent: function (product_id) { 2742 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2743 return; 2744 2745 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2746 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 2747 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2748 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params) 2749 event.trackingIds = window.pysWooProductData[product_id]['ga']['trackingIds']; 2750 this.fireEvent(event.name, event); 2751 } 2752 } 2753 2754 }, 2755 2756 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 2757 2758 window.pysWooProductData = window.pysWooProductData || []; 2759 2760 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2761 return; 2762 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 2763 2764 if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) { 2765 product_id = parseInt($form.find('input[name="variation_id"]').val()); 2766 } 2767 2768 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2769 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 2770 2771 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params); 2772 2773 2774 if(product_type === Utils.PRODUCT_GROUPED ) { 2775 var groupValue = 0; 2776 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 2777 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 2778 var quantity = parseInt($(this).val()); 2779 if(isNaN(quantity)) { 2780 quantity = 0; 2781 } 2782 var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
2783 event.params.items.forEach(function(el,index,array) { 2784 if(el.id == childItem.content_id) { 2785 if(quantity > 0){ 2786 el.quantity = quantity; 2787 el.price = childItem.price; 2788 } else { 2789 array.splice(index, 1); 2790 } 2791 } 2792 }); 2793 groupValue += childItem.price * quantity; 2794 }); 2795 2796 if(options.woo.addToCartOnButtonValueEnabled && 2797 options.woo.addToCartOnButtonValueOption !== 'global' && 2798 event.params.hasOwnProperty('ecomm_totalvalue')) { 2799 event.params.ecomm_totalvalue = groupValue; 2800 } 2801 2802 if(groupValue == 0) return; // skip if no items selected 2803 } else { 2804 // update items qty param 2805 event.params.items[0].quantity = qty; 2806 } 2807 2808 // maybe customize value option 2809 if (options.woo.addToCartOnButtonValueEnabled && 2810 options.woo.addToCartOnButtonValueOption !== 'global' && 2811 product_type !== Utils.PRODUCT_GROUPED) 2812 { 2813 if(event.params.hasOwnProperty('ecomm_totalvalue')) { 2814 event.params.ecomm_totalvalue = event.params.items[0].price * qty; 2815 } 2816 } 2817 2818 2819 2820 var eventName = is_external ? options.woo.affiliateEventName : event.name; 2821 eventName = normalizeEventName(eventName); 2822 2823 this.fireEvent(eventName, event); 2824 2825 } 2826 } 2827 2828 }, 2829 2830 onWooCheckoutProgressStep: function (event) { 2831 this.fireEvent(event.name, event); 2832 }, 2833 2834 onWooSelectContent: function (event) { 2835 this.fireEvent(event.name, event); 2836 }, 2837 2838 onWooRemoveFromCartEvent: function (event) { 2839 this.fireEvent(event.name, event); 2840 }, 2841 2842 onWooAffiliateEvent: function (product_id) { 2843 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 2844 return; 2845 var event = options.dynamicEvents.woo_affiliate[this.tag()]; 2846 2847 if (window.pysWooProductData.hasOwnProperty(product_id)) { 2848 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 2849 2850 event = Utils.clone(event ); 2851 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params) 2852 this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event); 2853 2854 } 2855 } 2856 2857 }, 2858 2859 onWooPayPalEvent: function (event) { 2860 this.fireEvent(event.name, event); 2861 }, 2862 2863 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 2864 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 2865 return; 2866 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 2867 2868 2869 if (window.pysEddProductData.hasOwnProperty(download_id)) { 2870 2871 var index; 2872 2873 if (price_index) { 2874 index = download_id + '_' + price_index; 2875 } else { 2876 index = download_id; 2877 } 2878 2879 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 2880 if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) { 2881 2882 Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params); 2883 2884 // update items qty param 2885 event.params.items[0].quantity = qty; 2886 2887 this.fireEvent(event.name,event); 2888 2889 } 2890 } 2891 2892 } 2893 2894 }, 2895 2896 onEddRemoveFromCartEvent: function (event) { 2897 this.fireEvent(event.name, event); 2898 }, 2899 2900 onPageScroll: function (event) { 2901 if (initialized && this.isEnabled()) { 2902 this.fireEvent(event.name, event); 2903 } 2904 }, 2905 onTime: function (event) { 2906 if (initialized && this.isEnabled()) { 2907 this.fireEvent(event.name, event); 2908 } 2909 }, 2910 }; 2911 2912 }(options); 2913 2914 var GAds = function (options) { 2915 2916 var initialized = false;
2917 2918 /** 2919 * Fires event 2920 * 2921 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 2922 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 2923 * @link: https://developers.google.com/gtagjs/reference/event 2924 * @link: https://developers.google.com/gtagjs/reference/parameter 2925 */ 2926 function fireEvent(name, data) { 2927 2928 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(event_name,'google_ads')) { 2929 return; 2930 } 2931 2932 var _params = Utils.copyProperties(data.params,{}); 2933 var ids = data.ids; 2934 2935 var conversion_labels = data.conversion_labels; 2936 Utils.copyProperties(Utils.getRequestParams(), _params); 2937 var _fireEvent = function (conversion_id,event_name) { 2938 2939 params = Utils.copyProperties(_params, { send_to: conversion_id }); 2940 2941 if("conversion" === event_name) { 2942 delete params.items; 2943 delete params.ecomm_pagetype; 2944 delete params.ecomm_prodid; 2945 delete params.ecomm_totalvalue; 2946 } 2947 2948 if (options.debug) { 2949 console.log('[Google Ads #' + conversion_id + '] ' + event_name, params); 2950 } 2951 2952 gtag('event', event_name, params); 2953 2954 }; 2955 2956 if(conversion_labels.length > 0) { // if custom event have conversion_label 2957 conversion_labels.forEach(function (conversion_id) { 2958 _fireEvent(conversion_id,name); 2959 }); 2960 } else { // if normal event have conversion_label or custom without conversion_label 2961 2962 data.conversion_ids.forEach(function (conversion_id) { // send main event 2963 _fireEvent(conversion_id,name); 2964 }); 2965 2966 if (ids.length) { 2967 ids.forEach(function (conversion_id) { // send conversion event next to main(not use for custom events) 2968 _fireEvent(conversion_id,"conversion"); 2969 }); 2970 } 2971 } 2972 } 2973 2974 function normalizeEventName(eventName) { 2975 2976 var matches = { 2977 ViewContent: 'view_item', 2978 AddToCart: 'add_to_cart', 2979 AddToWishList: 'add_to_wishlist', 2980 InitiateCheckout: 'begin_checkout', 2981 Purchase: 'purchase', 2982 Lead: 'generate_lead', 2983 CompleteRegistration: 'sign_up', 2984 AddPaymentInfo: 'set_checkout_option' 2985 }; 2986 2987 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 2988 2989 } 2990 2991 /** 2992 * Public API 2993 */ 2994 return { 2995 tag: function() { 2996 return "google_ads"; 2997 }, 2998 isEnabled: function () { 2999 return options.hasOwnProperty('google_ads'); 3000 }, 3001 3002 disable: function () { 3003 initialized = false; 3004 }, 3005 3006 loadPixel: function () { 3007 3008 if (initialized || !this.isEnabled() || !Utils.consentGiven('google_ads')) { 3009 return; 3010 } 3011 3012 Utils.loadGoogleTag(options.google_ads.conversion_ids[0]); 3013 3014 // configure conversion ids 3015 options.google_ads.conversion_ids.forEach(function (conversion_id,index) { 3016 3017 3018 if(options.google_ads.enhanced_conversion.includes("index_"+index) 3019 && Object.keys(options.google_ads.user_data).length > 0 3020 ) { 3021 gtag('config', conversion_id,{ 'allow_enhanced_conversions':true }); 3022 gtag('set', 'user_data', options.google_ads.user_data); 3023 } else { 3024 gtag('config', conversion_id); 3025 } 3026 3027 }); 3028 3029 initialized = true; 3030 3031 Utils.fireStaticEvents('google_ads'); 3032 3033 }, 3034 3035 fireEvent: function (name, data) { 3036 3037 if (!initialized || !this.isEnabled()) { 3038 return false;
3039 } 3040 3041 data.delay = data.delay || 0; 3042 data.params = data.params || {}; 3043 data.ids = data.ids || []; 3044 data.conversion_labels = data.conversion_labels || []; 3045 3046 if (data.delay === 0) { 3047 fireEvent(name, data); 3048 } else { 3049 setTimeout(function (name, data) { 3050 fireEvent(name, data); 3051 }, data.delay * 1000, name, data); 3052 } 3053 3054 return true; 3055 3056 }, 3057 3058 onAdSenseEvent: function (event) { 3059 // not supported 3060 }, 3061 3062 onClickEvent: function (action, params) { 3063 //disabled 3064 }, 3065 3066 onWatchVideo: function (event) { 3067 this.fireEvent(event.name, event); 3068 }, 3069 3070 onCommentEvent: function (event) { 3071 this.fireEvent(event.name, event); 3072 }, 3073 3074 onFormEvent: function (event) { 3075 this.fireEvent(event.name, event); 3076 }, 3077 3078 onDownloadEvent: function (event) { 3079 this.fireEvent(event.name, event); 3080 }, 3081 3082 3083 3084 3085 onWooAddToCartOnButtonEvent: function (product_id) { 3086 3087 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3088 return; 3089 3090 if (window.pysWooProductData.hasOwnProperty(product_id)) { 3091 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 3092 3093 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 3094 Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']['params'].params, event.params) 3095 event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids'] 3096 event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels'] 3097 this.fireEvent(event.name, event); 3098 } 3099 } 3100 3101 }, 3102 3103 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 3104 3105 window.pysWooProductData = window.pysWooProductData || []; 3106 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3107 return; 3108 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 3109 3110 if (product_type === Utils.PRODUCT_VARIABLE && !options.google_ads.wooVariableAsSimple) { 3111 product_id = parseInt($form.find('input[name="variation_id"]').val()); 3112 } 3113 3114 if (window.pysWooProductData.hasOwnProperty(product_id)) { 3115 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 3116 3117 Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']["params"], event.params); 3118 event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids'] 3119 event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels'] 3120 3121 var groupValue = 0; 3122 if(product_type === Utils.PRODUCT_GROUPED ) { 3123 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 3124 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 3125 var quantity = parseInt($(this).val()); 3126 if(isNaN(quantity)) { 3127 quantity = 0; 3128 } 3129 3130 var childItem = window.pysWooProductData[product_id]['google_ads'].grouped[childId]; 3131 3132 if(options.woo.addToCartOnButtonValueEnabled && 3133 options.woo.addToCartOnButtonValueOption !== 'global') { 3134
3135 event.params.items.forEach(function(el,index,array) { 3136 if(el.id == childItem.content_id) { 3137 if(quantity > 0){ 3138 el.quantity = quantity; 3139 el.price = childItem.price; 3140 } else { 3141 array.splice(index, 1); 3142 } 3143 } 3144 }); 3145 } 3146 groupValue += childItem.price * quantity; 3147 }); 3148 if(groupValue == 0) return; 3149 event.params.value = groupValue; 3150 } else { 3151 // update items qty param 3152 event.params.items[0].quantity = qty; 3153 } 3154 3155 3156 3157 // maybe customize value option 3158 if (options.woo.addToCartOnButtonValueEnabled && 3159 options.woo.addToCartOnButtonValueOption !== 'global' && 3160 product_type !== Utils.PRODUCT_GROUPED) { 3161 event.params.value = event.params.value * qty; 3162 } 3163 3164 3165 3166 var eventName = is_external ? options.woo.affiliateEventName : event.name; 3167 eventName = normalizeEventName(eventName); 3168 3169 this.fireEvent(eventName, event); 3170 3171 } 3172 } 3173 3174 }, 3175 3176 onWooRemoveFromCartEvent: function (event) { 3177 this.fireEvent(event.name, event); 3178 }, 3179 3180 onWooAffiliateEvent: function (product_id) { 3181 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 3182 return; 3183 var event = options.dynamicEvents.woo_affiliate[this.tag()]; 3184 3185 if (window.pysWooProductData.hasOwnProperty(product_id)) { 3186 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 3187 3188 event = Utils.clone(event) 3189 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params) 3190 this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event); 3191 3192 } 3193 } 3194 3195 }, 3196 3197 onWooPayPalEvent: function (event) { 3198 this.fireEvent(event.name, event); 3199 }, 3200 3201 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 3202 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3203 return; 3204 var event = options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]; 3205 3206 3207 if (window.pysEddProductData.hasOwnProperty(download_id)) { 3208 3209 var index; 3210 3211 if (price_index) { 3212 index = download_id + '_' + price_index; 3213 } else { 3214 index = download_id; 3215 } 3216 3217 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 3218 if (window.pysEddProductData[download_id][index].hasOwnProperty('google_ads')) { 3219 3220 event = Utils.clone(event) 3221 Utils.copyProperties(window.pysEddProductData[download_id][index]['google_ads']['params'], event.params); 3222 event.ids = window.pysEddProductData[download_id][index]['google_ads']['ids'] 3223 // update items qty param 3224 //params.items[0].quantity = qty; 3225 3226 this.fireEvent(event.name, event); 3227 3228 } 3229 } 3230 3231 } 3232 3233 }, 3234 3235 onEddRemoveFromCartEvent: function (event) { 3236 this.fireEvent(event.name, event); 3237 }, 3238 onPageScroll: function (event) { 3239 if (initialized && this.isEnabled()) { 3240 this.fireEvent(event.name, event); 3241 } 3242 }, 3243 onTime: function (event) { 3244 if (initialized && this.isEnabled()) { 3245 this.fireEvent(event.name, event); 3246 } 3247 }, 3248 3249 }; 3250 3251 }(options); 3252
3253 window.pys = window.pys || {}; 3254 window.pys.Facebook = Facebook; 3255 window.pys.Analytics = Analytics; 3256 window.pys.GAds = GAds; 3257 window.pys.Utils = Utils; 3258 window.pys.TikTok = TikTok; 3259 3260 3261 3262 $(document).ready(function () { 3263 3264 3265 if($("#pys_late_event").length > 0) { 3266 var events = JSON.parse($("#pys_late_event").attr("dir")); 3267 for(var key in events) { 3268 var event = {}; 3269 event[events[key].e_id] = [events[key]]; 3270 if(options.staticEvents.hasOwnProperty(key)) { 3271 Object.assign(options.staticEvents[key], event); 3272 } else { 3273 options.staticEvents[key] = event; 3274 } 3275 3276 } 3277 } 3278 3279 var Pinterest = Utils.setupPinterestObject(); 3280 var Bing = Utils.setupBingObject(); 3281 3282 Utils.manageCookies(); 3283 Utils.initializeRequestParams(); 3284 Utils.setupGdprCallbacks(); 3285 3286 // setup Click Event 3287 if ( 3288 options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") || 3289 options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") || 3290 options.dynamicEvents.hasOwnProperty("automatic_event_tel_link") || 3291 options.dynamicEvents.hasOwnProperty("automatic_event_email_link") || 3292 options.dynamicEvents.hasOwnProperty("automatic_event_download") 3293 ) { 3294 3295 $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) { 3296 3297 var $elem = $(this); 3298 3299 3300 // Download 3301 if(options.dynamicEvents.hasOwnProperty("automatic_event_download")) { 3302 var isFired = false; 3303 if ($elem.is('a')) { 3304 var href = $elem.attr('href'); 3305 if (typeof href !== "string") { 3306 return; 3307 } 3308 href = href.trim(); 3309 var extension = Utils.getLinkExtension(href); 3310 var track_download = false; 3311 3312 if (extension.length > 0) { 3313 3314 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) { 3315 var pixels = Object.keys(options.dynamicEvents.automatic_event_download); 3316 for (var i = 0; i < pixels.length; i++) { 3317 var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]); 3318 var extensions = event.extensions; 3319 if (extensions.includes(extension)) { 3320 3321 if(pixels[i] == "tiktok") { 3322 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3323 } else { 3324 if (options.enable_remove_download_url_param) { 3325 href = href.split('?')[0]; 3326 } 3327 event.params.download_url = href; 3328 event.params.download_type = extension; 3329 event.params.download_name = Utils.getLinkFilename(href); 3330 getPixelBySlag(pixels[i]).onDownloadEvent(event); 3331 } 3332 3333 isFired = true; 3334 } 3335 } 3336 } 3337 } 3338 } 3339 if(isFired) { // prevent duplicate events on the same element 3340 return; 3341 } 3342 } 3343 3344 3345 if (!e.hasOwnProperty('originalEvent')) { 3346 return; 3347 } 3348 if($elem.hasClass("add_to_cart_button") || 3349 $elem.hasClass("single_add_to_cart_button") ) { // add_to_cart_button fire in woo 3350 return; 3351 } 3352 3353 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click") 3354 && $elem.hasClass("wcf-next-step-link")) { 3355 return;// add_to_cart_button fire in woo cf 3356 } 3357 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") 3358 && $elem.hasClass("wcf-bump-order-cb")) { 3359 return;// add_to_cart_button fire in woo cf 3360 } 3361 3362 if($elem.hasClass("remove_from_cart_button") ) { // cancel remove from cart 3363 return; 3364 } 3365 if($elem.hasClass("remove") ) { // cancel remove from cart 3366 if($elem.parents('.cart_item').length || $elem.parents('.mini_cart_item').length) 3367 return; 3368 } 3369 if($elem.attr("name") == "update_cart" || $elem.attr("name") == "apply_coupon") { // cancel update c
3369art or coupon button 3370 return; 3371 } 3372 3373 3374 if ($elem.hasClass('pys_block')) { 3375 return; // avoiding fake double clicks from Affiliate event 3376 } 3377 var text = ""; 3378 var target_url = ""; 3379 var linkType = "Internal Click"; 3380 3381 if ($elem.is('a')) { 3382 var href = $elem.attr('href'); 3383 3384 // fixes #112 3385 if (typeof href !== "string") { 3386 return; 3387 } 3388 href = href.trim(); 3389 3390 text = $elem.text(); 3391 if(options.enable_remove_target_url_param) { 3392 target_url = href.split('?')[0]; 3393 } else { 3394 target_url = href 3395 } 3396 3397 3398 //Email Event 3399 if (href.startsWith('mailto:')) { 3400 if(options.dynamicEvents.hasOwnProperty("automatic_event_email_link")) { 3401 var pixels = Object.keys(options.dynamicEvents.automatic_event_email_link); 3402 for(var i = 0;i<pixels.length;i++) { 3403 var event = Utils.clone(options.dynamicEvents.automatic_event_email_link[pixels[i]]); 3404 Utils.copyProperties(Utils.getRequestParam
3404s(), event.params); 3405 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3406 } 3407 } 3408 3409 return; // not fire next 3410 } 3411 3412 // Phone 3413 if (href.startsWith('tel:')) { 3414 if(options.dynamicEvents.hasOwnProperty("automatic_event_tel_link")) { 3415 var pixels = Object.keys(options.dynamicEvents.automatic_event_tel_link); 3416 for(var i = 0;i<pixels.length;i++) { 3417 var event = Utils.clone(options.dynamicEvents.automatic_event_tel_link[pixels[i]]); 3418 Utils.copyProperties(Utils.getRequestParams(), event.params); 3419 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3420 } 3421 } 3422 return; // not fire next 3423 } 3424 3425 if (href.startsWith('http')) { 3426 // link type 3427 var host = $elem.context != undefined ? $elem.context.host : $elem[0].host; 3428 if (document.location.host != host) { 3429 linkType = 'External Click'; 3430 } 3431 } 3432 } else if ($elem.is('button')) { 3433 if( $elem.hasClass("forminator-button-submit")) { 3434 //disable duplicate events 3435 return; 3436 } 3437 text = $elem.text(); 3438 } else if ($elem.is('input[type="button"]')) { 3439 text = $elem.val(); 3440 } else if ($elem.is('input[type="submit"]')) { 3441 if ( $elem.parents("form.comment-form")) { 3442 //disable duplicate events 3443 return; 3444 } 3445 if ($elem.parents("form")) { 3446 //disable duplicate events 3447 return; 3448 } 3449 text = $elem.val(); 3450 } else { 3451 return; 3452 } 3453 3454 3455 3456 text = Utils.filterEmails(text); 3457 3458 3459 if( linkType === "Internal Click" 3460 && options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") 3461 ) { 3462 var pixels = Object.keys(options.dynamicEvents.automatic_event_internal_link); 3463 3464 for(var i = 0;i<pixels.length;i++) { 3465 var event = Utils.clone(options.dynamicEvents.automatic_event_internal_link[pixels[i]]); 3466 3467 if(pixels[i] !== "tiktok") { // TT doesn't support custom parameters 3468 event.params["text"] = text; 3469 if(target_url){ 3470 event.params["target_url"] = target_url; 3471 } 3472 Utils.copyProperties(Utils.getRequestParam
3472s(), event.params); 3473 } 3474 3475 3476 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3477 } 3478 } 3479 3480 if( linkType === "External Click" 3481 && options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") 3482 ) { 3483 var pixels = Object.keys(options.dynamicEvents.automatic_event_outbound_link); 3484 3485 for(var i = 0;i<pixels.length;i++) { 3486 var event = Utils.clone(options.dynamicEvents.automatic_event_outbound_link[pixels[i]]); 3487 3488 if(pixels[i] !== "tiktok") { // TT doesn't support custom parameters 3489 event.params["text"] = text; 3490 if(target_url){ 3491 event.params["target_url"] = target_url; 3492 } 3493 Utils.copyProperties(Utils.getRequestParams(), event.params); 3494 } 3495 3496 3497 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3498 } 3499 } 3500 3501 3502 3503 3504 }); 3505 3506 } 3507 3508 // setup AdSense Event 3509 if (options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) { 3510 3511 var isOverGoogleAd = false; 3512 3513 $(document) 3514 .on('mouseover', 'ins > ins > iframe', function () { 3515 isOverGoogleAd = true; 3516 }) 3517 .on('mouseout', 'iframe', function () { 3518 isOverGoogleAd = false; 3519 }); 3520 3521 $(window) 3522 .on( "blur",function () { 3523 if (isOverGoogleAd) { 3524 3525 if(options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) { 3526 var pixels = Object.keys(options.dynamicEvents.automatic_event_adsense); 3527 for (var i = 0; i < pixels.length; i++) { 3528 var event = Utils.clone(options.dynamicEvents.automatic_event_adsense[pixels[i]]); 3529 Utils.copyProperties(Utils.getRequestParam
3529s(), event.params); 3530 getPixelBySlag(pixels[i]).onAdSenseEvent(event); 3531 } 3532 } 3533 3534 $.each(options.triggerEventTypes, function (triggerType, events) { 3535 $.each(events, function (eventId, triggers) { 3536 switch (triggerType) { 3537 case 'ad_sense_click': 3538 Utils.fireTriggerEvent(eventId); 3539 break; 3540 } 3541 }); 3542 }); 3543 } 3544 }) 3545 .trigger("focus"); 3546 3547 } 3548 3549 //setup adsense for custom events 3550 var dynamicAdsenseEventsTriggers = 0 3551 $.each(options.triggerEventTypes, function (triggerType, events) { 3552 if(triggerType == "ad_sense_click") { 3553 dynamicAdsenseEventsTriggers++; 3554 } 3555 }); 3556 if (dynamicAdsenseEventsTriggers > 0) { 3557 3558 var isOverGoogleAd = false; 3559 3560 $(document) 3561 .on('mouseover', 'ins > ins > iframe', function () { 3562 isOverGoogleAd = true; 3563 }) 3564 .on('mouseout', 'iframe', function () { 3565 isOverGoogleAd = false; 3566 }); 3567 3568 $(window) 3569 .on( "blur",function () { 3570 if (isOverGoogleAd) { 3571 3572 $.each(options.triggerEventTypes, function (triggerType, events) { 3573 $.each(events, function (eventId, triggers) { 3574 switch (triggerType) { 3575 case 'ad_sense_click': 3576 Utils.fireTriggerEvent(eventId); 3577 break; 3578 } 3579 }); 3580 }); 3581 } 3582 }) 3583 .trigger("focus"); 3584 3585 } 3586 3587 3588 // page scroll event 3589 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll") 3590 ) { 3591 3592 var singlePageScroll = function () { 3593 3594 3595 var docHeight = $(document).height() - $(window).height(); 3596 var isFired = false; 3597 3598 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) { 3599 var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll); 3600 for(var i = 0;i<pixels.length;i++) { 3601 var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]); 3602 var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions 3603 3604 if(scroll < $(window).scrollTop()) { 3605 Utils.copyProperties(Utils.getRequestParam
3605s(), event.params); 3606 getPixelBySlag(pixels[i]).onPageScroll(event); 3607 isFired = true 3608 } 3609 } 3610 } 3611 if(isFired) { 3612 $(document).off("scroll",singlePageScroll); 3613 } 3614 } 3615 $(document).on("scroll",singlePageScroll); 3616 } 3617 3618 3619 if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) { 3620 var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page); 3621 var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel 3622 setTimeout(function(){ 3623 for(var i = 0;i<pixels.length;i++) { 3624 var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]); 3625 Utils.copyProperties(Utils.getRequestParams(), event.params); 3626 getPixelBySlag(pixels[i]).onTime(event); 3627 } 3628 },time*1000); 3629 } 3630 3631 // setup Dynamic events 3632 $.each(options.triggerEventTypes, function (triggerType, events) { 3633 3634 $.each(events, function (eventId, triggers) { 3635 3636 switch (triggerType) { 3637 case 'url_click': 3638 //@see: Utils.setupURLClickEvents() 3639 break; 3640 3641 case 'css_click': 3642 Utils.setupCSSClickEvents(eventId, triggers); 3643 break; 3644 3645 case 'css_mouseover': 3646 Utils.setupMouseOverClickEvents(eventId, triggers); 3647 break; 3648 3649 case 'scroll_pos': 3650 Utils.setupScrollPosEvents(eventId, triggers); 3651 break; 3652 case 'comment': 3653 Utils.setupCommentEvents(eventId, triggers); 3654 break; 3655 } 3656 3657 }); 3658 3659 }); 3660 3661 // setup WooCommerce events 3662 if (options.woo.enabled) { 3663 3664 // Woo CartFlow AddToCart 3665 if (options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")) { 3666 $("body").on("click",'.wcf-next-step-link',function () { 3667 var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_next_step_click); 3668 for(var i = 0;i<pixels.length;i++) { 3669 var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_next_step_click[pixels[i]]) 3670 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3671 } 3672 }); 3673 } 3674 // Woo CartFlow Bump AddToCart 3675 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") || 3676 options.dynamicEvents.hasOwnProperty("wcf_bump")) { 3677 $("body").on('change','.wcf-bump-order-cb',function () { 3678 3679 if(this.checked) { 3680 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")) { 3681 var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_bump_click); 3682 for(var i = 0;i<pixels.length;i++) { 3683 var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_bump_click[pixels[i]]); 3684 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3685 } 3686 } 3687 3688 3689 if(options.dynamicEvents.hasOwnProperty("wcf_bump")) { 3690 var pixels = Object.keys(options.dynamicEvents.wcf_bump); 3691 for(var i = 0;i<pixels.length;i++) { 3692 var event = Utils.clone(options.dynamicEvents.wcf_bump[pixels[i]]); 3693 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3694 } 3695 } 3696 3697 } else { 3698 if(options.dynamicEvents.hasOwnProperty("wcf_remove_from_cart_on_bump_click")) { 3699 var pixels = Object.keys(options.dynamicEvents.wcf_remove_from_cart_on_bump_click); 3700 for(var i = 0;i<pixels.length;i++) { 3701 var event = Utils.clone(options.dynamicEvents.wcf_remove_from_cart_on_bump_click[pixels[i]]); 3702 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 3703 } 3704 } 3705 3706 } 3707 3708 3709 }); 3710 } 3711 3712 3713 // WooCommerce AddToCart 3714 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click") 3715 && options.woo.hasOwnProperty("addToCartCatchMethod") 3716 && options.woo.addToCartCatchMethod === "add_cart_js" 3717 ) { 3718 3719 // Loop, any kind of "simple" product, except external 3720 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 3721 3722 var product_id = $(this).data('product_id'); 3723 3724 if (typeof product_id !== 'undefined') { 3725 Facebook.onWooAddToCartOnButtonEvent(product_id,$(this)); 3726 Analytics.onWooAddToCartOnButtonEvent(product_id); 3727 GAds.onWooAddToCartOnButtonEvent(product_id); 3728 Pinterest.onWooAddToCartOnButtonEvent(product_id); 3729 Bing.onWooAddToCartOnButtonEvent(product_id); 3730 TikTok.onWooAddToCartOnButtonEvent(product_id); 3731 } 3732 3733 }); 3734 3735 // Single Product 3736 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 3737 // $(document) not work 3738 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 3739 3740 var $button = $(this); 3741 3742 if ($button.hasClass('disabled')) { 3743 return; 3744 } 3745 3746 var $form = $button.closest('form'); 3747 3748 var product_type = Utils.PRODUCT_SIMPLE; 3749 var is_external = false;
3750 3751 if ($form.length === 0) { 3752 is_external = true; 3753 } else if ($form.hasClass('variations_form')) { 3754 product_type = Utils.PRODUCT_VARIABLE; 3755 } else if($form.hasClass('bundle_form')) { 3756 product_type = Utils.PRODUCT_BUNDLE; 3757 } else if($form.hasClass('grouped_form')) { 3758 product_type = Utils.PRODUCT_GROUPED; 3759 } 3760 3761 3762 3763 var product_id; 3764 var qty; 3765 if (product_type === Utils.PRODUCT_GROUPED) { 3766 qty = 1; 3767 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3768 } else if (product_type === Utils.PRODUCT_VARIABLE) { 3769 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3770 var qtyTag = $form.find('input[name="quantity"]'); 3771 if(qtyTag.length <= 0) { 3772 qtyTag = $form.find('select[name="quantity"]'); 3773 } 3774 qty = parseInt(qtyTag.val()); 3775 } else if (is_external) { 3776 product_id = options.woo.singleProductId; 3777 qty = 1; 3778 } else { 3779 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 3780 var qtyTag = $form.find('input[name="quantity"]'); 3781 if(qtyTag.length <= 0) { 3782 qtyTag = $form.find('select[name="quantity"]'); 3783 } 3784 qty = parseInt(qtyTag.val()); 3785 } 3786 3787 Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3788 Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3789 GAds.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3790 Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3791 Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3792 TikTok.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 3793 }); 3794 3795 } 3796 3797 // WooCommerce Affiliate 3798 if (options.dynamicEvents.hasOwnProperty("woo_affiliate")) { 3799 3800 // Loop, external 3801 $('.product_type_external').on("click",function (e) { 3802 3803 var product_id = $(this).data('product_id'); 3804 3805 if (typeof product_id !== 'undefined') { 3806 Facebook.onWooAffiliateEvent(product_id); 3807 Analytics.onWooAffiliateEvent(product_id); 3808 GAds.onWooAffiliateEvent(product_id); 3809 Pinterest.onWooAffiliateEvent(product_id); 3810 Bing.onWooAffiliateEvent(product_id); 3811 } 3812 3813 }); 3814 3815 } 3816 3817 // WooCommerce RemoveFromCart 3818 if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) { 3819 3820 $('body').on('click', options.woo.removeFromCartSelector, function (e) { 3821 3822 var $a = $(e.currentTarget), 3823 href = $a.attr('href'); 3824 3825 // extract cart item hash from remove button URL 3826 var regex = new RegExp("[\\?&]remove_item=([^&#]*)"), 3827 results = regex.exec(href); 3828 3829 if (results !== null) { 3830 3831 var item_hash = results[1]; 3832 3833 if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) { 3834 var events = options.dynamicEvents["woo_remove_from_cart"][item_hash]; 3835 Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events) 3836 } 3837 3838 } 3839 3840 }); 3841 3842 } 3843 3844 // WooCommerce PayPal 3845 if (options.dynamicEvents.hasOwnProperty("woo_paypal")) { 3846 3847 // Non-default binding used to avoid situations when some code in external js 3848 // stopping events propagation, eg. returns false, and our handler will never called 3849 $(document).onFirst('submit click', '#place_order', function (e) { 3850 3851 var method = $('form[name="checkout"] input[name="payment_method"]:checked').val(); 3852 3853 if (method !== 'paypal') { 3854 return; 3855 } 3856 var events = options.dynamicEvents.woo_paypal; 3857 Utils.fireEventForAllPixel("onWooPayPalEvent",events) 3858 3859 }); 3860 3861 } 3862 3863 // WooCommerce checkout progress 3864 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_f") ) { 3865 3866 $(document).on("change",".woocommerce-validated #billing_first_name",function () { 3867 Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_f[Analytics.tag()]); 3868 }); 3869 } 3870 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_l")) { 3871 3872 $(document).on("change",".woocommerce-validated #billing_last_name",function () { 3873 Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_l[Analytics.tag()]); 3874 }); 3875 } 3876 3877 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_e")) { 3878 3879 $(document).on("change",".woocommerce-validated #billing_email",function () { 3880 Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_e[Analytics.tag()]); 3881 }); 3882 } 3883 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_o")) { 3884 $(document).onFirst('submit click', '#place_order', function () { 3885 Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_o[Analytics.tag()]); 3886 }); 3887 } 3888 3889 3890 // WooCommerce 3891 if(options.dynamicEvents.hasOwnProperty("woo_select_content_search") || 3892 options.dynamicEvents.hasOwnProperty("woo_select_content_shop") || 3893 options.dynamicEvents.hasOwnProperty("woo_select_content_tag") || 3894 options.dynamicEvents.hasOwnProperty("woo_select_content_single") || 3895 options.dynamicEvents.hasOwnProperty("woo_select_content_category") 3896 ) { 3897 $('.product.type-product a.woocommerce-loop-product__link').onFirst('click', function (evt) { 3898 var productId = $(this).parent().find("a.add_to_cart_button").attr("data-product_id"); 3899 if(options.dynamicEvents.hasOwnProperty("woo_select_content_search") && 3900 options.dynamicEvents.woo_select_content_search.hasOwnProperty(productId)) { 3901 Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_search[productId][Analytics.tag()]); 3902 } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_shop") && 3903 options.dynamicEvents.woo_select_content_shop.hasOwnProperty(productId)) { 3904 Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_shop[productId][Analytics.tag()]); 3905 } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_tag") && 3906 options.dynamicEvents.woo_select_content_tag.hasOwnProperty(productId)) { 3907 Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_tag[productId][Analytics.tag()]); 3908 } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_single") && 3909 options.dynamicEvents.woo_select_content_single.hasOwnProperty(productId)) { 3910 Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_single[productId][Analytics.tag()]); 3911 } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_category") && 3912 options.dynamicEvents.woo_select_content_category.hasOwnProperty(productId)) { 3913 Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_category[productId][Analytics.tag()]); 3914 } 3915 }); 3916 } 3917 } 3918 3919 // setup EDD events 3920 if (options.edd.enabled) { 3921 3922 // EDD AddToCart 3923 if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) { 3924 3925 $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) { 3926 3927 var $button = $(this); 3928 var $form = $button.closest('form'); 3929 var variable_price = $button.data('variablePrice'); // yes/no 3930 var price_mode = $button.data('priceMode'); // single/multi 3931 var ids = []; 3932 var quantities = []; 3933 var qty; 3934 var id; 3935 3936 if (variable_price === 'yes' && price_mode === 'multi') { 3937 3938 id = $form.find('input[name="download_id"]').val(); 3939 3940 // get selected variants 3941 $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) { 3942 ids.push(id + '_' + $(el).val()); 3943 }); 3944 3945 // get qty for selected variants 3946 $.each(ids, function (i, variant_id) { 3947 3948 var variant_index = variant_id.split('_', 2); 3949 qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val(); 3950 3951 if (typeof qty !== 'undefined') { 3952 quantities.push(qty); 3953 } else { 3954 quantities.push(1); 3955 } 3956 3957 }); 3958 3959 } else if (variable_price === 'yes' && price_mode === 'single') { 3960 3961 id = $form.find('input[name="download_id"]').val(); 3962 ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val()); 3963 3964 qty = $form.find('input[name="edd_download_quantity"]').val(); 3965 3966 if (typeof qty !== 'undefined') { 3967 quantities.push(qty); 3968 } else { 3969 quantities.push(1); 3970 } 3971 3972 } else { 3973 3974 ids.push($button.data('downloadId')); 3975 3976 qty = $form.find('input[name="edd_download_quantity"]').val(); 3977 3978 if (typeof qty !== 'undefined') { 3979 quantities.push(qty); 3980 } else { 3981 quantities.push(1); 3982 } 3983 } 3984 3985 // fire event for each download/variant 3986 $.each(ids, function (i, download_id) { 3987 3988 var q = parseInt(quantities[i]); 3989 var variant_index = download_id.toString().split('_', 2); 3990 var price_index; 3991 3992 if (variant_index.length === 2) { 3993 download_id = variant_index[0]; 3994 price_index = variant_index[1]; 3995 } 3996 3997 Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3998 Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q); 3999 GAds.onEddAddToCartOnButtonEvent(download_id, price_index, q); 4000 Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q); 4001 Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q); 4002 TikTok.onEddAddToCartOnButtonEvent(download_id, price_index, q); 4003 4004 }); 4005 4006 }); 4007 4008 } 4009 4010 // EDD RemoveFromCart 4011 if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) { 4012 4013 $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) { 4014 4015 var href = $(this).attr('href'); 4016 var key = href.substring(href.indexOf('=') + 1).charAt(0); 4017 4018 if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) { 4019 var events = options.dynamicEvents.edd_remove_from_cart[key]; 4020 Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events) 4021 } 4022 4023 }); 4024 4025 } 4026 4027 } 4028 4029 Utils.setupURLClickEvents(); 4030 4031 // setup Comment Event 4032 if (options.dynamicEvents.hasOwnProperty("automatic_event_c
4032omment") 4033 ) { 4034 4035 $('form.comment-form').on("submit",function () { 4036 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) { 4037 var pixels = Object.keys(options.dynamicEvents.automatic_event_comment); 4038 for (var i = 0; i < pixels.length; i++) { 4039 var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]); 4040 Utils.copyProperties(Utils.getRequestParams(), event.params); 4041 getPixelBySlag(pixels[i]).onCommentEvent(event); 4042 } 4043 } 4044 }); 4045 4046 } 4047 4048 // setup Form Event 4049 if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 4050 4051 $(document).onFirst('submit', 'form', function (e) { 4052 4053 var $form = $(this); 4054 4055 // exclude WP forms 4056 if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') { 4057 return; 4058 } 4059 4060 // exclude Woo forms 4061 if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') || 4062 $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) { 4063 return; 4064 } 4065 4066 // exclude EDD forms 4067 if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) { 4068 return; 4069 } 4070 4071 var params = { 4072 form_id: $form.attr('id'), 4073 form_class: $form.attr('class'), 4074 text: $form.find('[type="submit"]').is('input') ? 4075 $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text() 4076 }; 4077 4078 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 4079 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 4080 for (var i = 0; i < pixels.length; i++) { 4081 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 4082 4083 if(pixels[i] === "tiktok") { 4084 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 4085 } else { 4086 Utils.copyProperties(params, event.params,) 4087 Utils.copyProperties(Utils.getRequestParam
4087s(), event.params); 4088 getPixelBySlag(pixels[i]).onFormEvent(event); 4089 } 4090 } 4091 } 4092 }); 4093 4094 //Forminator 4095 $(document).on( 'forminator:form:submit:success', function( formData ){ 4096 var params = { 4097 form_id: $(formData.target).find('input[name="form_id"]').val(), 4098 text: $(formData.target).find('.forminator-button-submit').text() 4099 }; 4100 4101 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 4102 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 4103 for (var i = 0; i < pixels.length; i++) { 4104 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 4105 Utils.copyProperties(params, event.params) 4106 Utils.copyProperties(Utils.getRequestParams(), event.params); 4107 getPixelBySlag(pixels[i]).onFormEvent(event); 4108 } 4109 } 4110 }); 4111 4112 // Ninja Forms 4113 $(document).onFirst('nfFormSubmitResponse', function (e, data) { 4114 4115 var params = { 4116 form_id: data.response.data.form_id, 4117 text: data.response.data.settings.title 4118 }; 4119 4120 if(options.dynamicEvents.hasOwnProperty("automatic_event_form") ) { 4121 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 4122 for(var i = 0;i<pixels.length;i++) { 4123 var event = options.dynamicEvents.automatic_event_form[pixels[i]]; 4124 Utils.copyProperties(params,event.params) 4125 Utils.copyProperties(Utils.getRequestParam
4125s(), event.params); 4126 getPixelBySlag(pixels[i]).onFormEvent(event); 4127 } 4128 } 4129 4130 }); 4131 4132 } 4133 4134 // load pixel APIs 4135 Utils.loadPixels(); 4136 4137 // setup Enrich content 4138 if(Utils.isCheckoutPage()) { 4139 Utils.addCheckoutFields(); 4140 } 4141 }); 4142 4143 4144 // load WatchVideo event APIs for Auto 4145 if (options.automatic.enable_video) { 4146 /** 4147 * Real Cookie Banner. 4148 */ 4149 var consentApi = window.consentApi; 4150 if (consentApi && options.gdpr.real_cookie_banner_integration_enabled) { 4151 if (options.automatic.enable_youtube 4152 4153 ) { 4154 window.consentApi.consent("http", "CONSENT", ".youtube.com").then(Utils.initYouTubeAPI); 4155 } 4156 if (options.automatic.enable_vimeo 4157 4158 ) { 4159 window.consentApi.consent("http", "player", ".vimeo.com").then(Utils.initVimeoAPI); 4160 } 4161 }else{ 4162 if (options.automatic.enable_youtube 4163 ) { 4164 Utils.initYouTubeAPI(); 4165 } 4166 if (options.automatic.enable_vimeo 4167 ) { 4168 Utils.initVimeoAPI(); 4169 } 4170 } 4171 } 4172 4173 4174 4175}(jQuery, pysOptions); 4176 4177function pys_generate_token(length){ 4178 //edit the token allowed characters 4179 var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split(""); 4180 var b = []; 4181 for (var i=0; i<length; i++) { 4182 var j = (Math.random() * (a.length-1)).toFixed(0); 4183 b[i] = a[j]; 4184 } 4185 return b.join(""); 4186} 4187 4188function getBundlePriceOnSingleProduct(data) { 4189 var items_sum = 0; 4190 jQuery(".bundle_form .bundled_product").each(function(index){ 4191 var id = jQuery(this).find(".cart").data("bundled_item_id"); 4192 var item_price = data.prices[id]; 4193 var item_quantity = jQuery(this).find(".bundled_qty").val(); 4194 if(!jQuery(this).hasClass("bundled_item_optional") || 4195 jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) { 4196 items_sum += item_price*item_quantity; 4197 } 4198 }); 4199 return items_sum; 4200} 4201 4202function getPixelBySlag(slug) { 4203 switch (slug) { 4204 case "facebook": return window.pys.Facebook; 4205 case "ga": return window.pys.Analytics; 4206 case "google_ads": return window.pys.GAds; 4207 case "bing": return window.pys.Bing; 4208 case "pinterest": return window.pys.Pinterest; 4209 case "tiktok": return window.pys.TikTok; 4210 } 4211}
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.