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