1/* global pysOptions */ 2 3! function ($, options) { 4 if (options.debug) { 5 console.log('PYS:', options); 6 } 7 8 var uniqueId = {}; 9 10 var firstVisit = false; 11 12 var isTrackEventForGA = []; 13 14 var isAdsLoad = false; 15 16 let gtm_variables = {}; 17 let gtm_datalayername = "dynamicVariable"; 18 var domain = ''; 19 if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) { 20 domain = getRootDomain(true); 21 } 22 23 /** 24 * Resolve parameter value based on mode (static or dynamic) 25 * 26 * @param {Object|string} param - Parameter object with { value, selector } or string value 27 * @returns {string|null} - Resolved value 28 */ 29 function resolveParamValue(param, key = '') { 30 31 // 1ï¸â£ null / undefined - skip this parameter 32 if (param === null || param === undefined) { 33 return null; 34 } 35 36 // 2ï¸â£ primitive 37 if (typeof param !== 'object') { 38 return param; 39 } 40 41 // 3ï¸â£ array 42 if (Array.isArray(param)) { 43 return param.map(item => resolveParamValue(item, key)); 44 } 45 46 // 4ï¸â£ NEW FORMAT OBJECT (config-object) 47 const isConfigObject = 48 ('value' in param || 'selector' in param || 'dynamic' in param || 'input_type' in param) && 49 Object.keys(param).every(k => 50 ['value','selector','dynamic','input_type','name'].includes(k) 51 ); 52 53 if (isConfigObject) { 54 55 // STATIC MODE 56 const isStatic = 57 !param.dynamic || 58 !param.selector || 59 param.selector.trim() === ''; 60 61 if (isStatic) { 62 let value = param.value ?? null; 63 64 if (param.input_type === "float" || param.input_type === "int") { 65 value = extractNumericValue( 66 value, 67 param.input_type === "int" 68 ); 69 } 70 71 return value; 72 } 73 74 // DYNAMIC MODE 75 try { 76 const el = document.querySelector(param.selector); 77 if (!el) return null; 78 79 let value = 80 el.value ?? 81 el.innerText ?? 82 el.textContent ?? 83 el.getAttribute("content") ?? 84 el.getAttribute("data-value") ?? 85 null; 86 87 if (param.input_type === "float" || param.input_type === "int") { 88 value = extractNumericValue( 89 value, 90 param.input_type === "int" 91 ); 92 } 93 94 return value; 95 96 } catch { 97 return null; 98 } 99 } 100 101 // 5ï¸â£ Plain object (recursive traversal) - filter out null/undefined values 102 return Object.fromEntries( 103 Object.entries(param) 104 .map(([k, v]) => [k, resolveParamValue(v, k)]) 105 .filter(([k, v]) => v !== null && v !== undefined) 106 ); 107 } 108 109 function extractNumericValue(value, isInt=false) { 110 if (value === null || value === undefined) { 111 return null; 112 } 113 if (isInt) { 114 return parseInt(value); 115 } 116 return parseFloat(value); 117 } 118 119 var loadTags = []; 120 121 var dummyPinterest = function () { 122 123 /** 124 * Public API 125 */ 126 return { 127 tag: function() { 128 return "pinterest"; 129 }, 130 isEnabled: function () {}, 131 132 disable: function () {}, 133 134 loadPixel: function () {}, 135 136 fireEvent: function (name, data) { 137 return false; 138 }, 139 140 onAdSenseEvent: function (event) {}, 141 142 onClickEvent: function (params) {}, 143 144 onWatchVideo: function (params) {}, 145 146 onCommentEvent: function (event) {}, 147 148 onFormEvent: function (params) {}, 149 150 onDownloadEvent: function (params) {}, 151 152 153 154 onWooAddToCartOnButtonEvent: function (product_id) {}, 155 156 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {}, 157 158 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 159 160 onWooAffiliateEvent: function (product_id) {}, 161 162 onWooPayPalEvent: function (event) {}, 163 164 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 165 166 onEddRemoveFromCartEvent: function (item) {}, 167 168 onPageScroll: function (event) {}, 169 onTime: function (event) { 170 171 }, 172 173 } 174 175 }(); 176 177 var dummyBing = function () { 178 179 /** 180 * Public API 181 */ 182 return { 183 tag: function() { 184 return "bing"; 185 }, 186 isEnabled: function () {}, 187 188 disable: function () {}, 189 190 loadPixel: function () {}, 191 192 fireEvent: function (name, data) { 193 return false; 194 }, 195 196 onAdSenseEvent: function (event) {}, 197 198 onClickEvent: function (params) {}, 199 200 onWatchVideo: function (params) {}, 201 202 onCommentEvent: function (event) {}, 203 204 onFormEvent: function (params) {}, 205 206 onDownloadEvent: function (params) {}, 207 208 209 onWooAddToCartOnButtonEvent: function (product_id) {}, 210 211 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {}, 212 213 onWooRemoveFromCartEvent: function (cart_item_hash) {}, 214 215 onWooAffiliateEvent: function (product_id) {}, 216 217 onWooPayPalEvent: function (event) {}, 218 219 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {}, 220 221 onEddRemoveFromCartEvent: function (item) {}, 222 onPageScroll: function (event) {}, 223 onTime: function (event) { 224 225 }, 226 } 227 228 }(); 229 230 var dummyReddit = function () { 231 /** 232 * Public API 233 */ 234 return { 235 tag: function () { 236 return "reddit"; 237 }, 238 isEnabled: function () { 239 }, 240 241 disable: function () { 242 }, 243 244 loadPixel: function () { 245 }, 246 247 fireEvent: function ( name, data ) { 248 return false; 249 }, 250 251 onAdSenseEvent: function ( event ) { 252 }, 253 254 onClickEvent: function ( params ) { 255 }, 256 257 onWatchVideo: function ( params ) { 258 }, 259 260 onCommentEvent: function ( event ) { 261 }, 262 263 onFormEvent: function ( params ) { 264 }, 265 266 onDownloadEvent: function ( params ) { 267 }, 268 269 onWooAddToCartOnButtonEvent: function ( product_id ) { 270 }, 271 272 onWooAddToCartOnSingleEvent: function ( product_id, qty, product_type, is_external, $form ) { 273 }, 274 275 onWooRemoveFromCartEvent: function ( cart_item_hash ) { 276 }, 277 278 onWooAffiliateEvent: function ( product_id ) { 279 }, 280 281 onWooPayPalEvent: function ( event ) { 282 }, 283 284 onEddAddToCartOnButtonEvent: function ( download_id, price_index, qty ) { 285 }, 286 287 onEddRemoveFromCartEvent: function ( item ) { 288 }, 289 290 onPageScroll: function ( event ) { 291 }, 292 293 onTime: function ( event ) { 294 }, 295 } 296 }(); 297 298 var Utils = function (options) { 299 300 301 var Pinterest = dummyPinterest; 302 303 var Bing = dummyBing; 304 305 var Reddit = dummyReddit; 306 307 var gtag_loaded = false; 308 309 var gtm_loaded = false; 310 311 let isNewSession = checkSession(); 312 313 let dataLayerName = 'dataLayerPYS'; 314 315 let GTMdataLayerName = 'dataLayer'; 316 317 318 function loadPixels() { 319 320 if (!options.gdpr.all_disabled_by_api) { 321 if (!options.gdpr.tiktok_disabled_by_api) { 322 TikTok.loadPixel(); 323 } 324 325 if (!options.gdpr.facebook_disabled_by_api) { 326 Facebook.loadPixel(); 327 } 328 329 if (!options.gdpr.analytics_disabled_by_api) { 330 Analytics.loadPixel(); 331 } 332 333 if (!options.gdpr.google_ads_disabled_by_api) { 334 GAds.loadPixel(); 335 } 336 337 if (!options.gdpr.analytics_disabled_by_api) { 338 GTM.loadPixel(); 339 } 340 341 if (!options.gdpr.pinterest_disabled_by_api) { 342 Pinterest.loadPixel(); 343 } 344 345 if (!options.gdpr.bing_disabled_by_api) { 346 Bing.loadPixel(); 347 } 348 349 if (!options.gdpr.reddit_disabled_by_api) { 350 Reddit.loadPixel(); 351 } 352 353 } 354 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 355 if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) { 356 Analytics.loadPixel(); 357 } 358 if (typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) { 359 GAds.loadPixel(); 360 } 361 } 362 } 363 364 /** 365 * WATCHVIDEO UTILS 366 */ 367 368 function isJSApiAttrEnabled(url) { 369 return url.indexOf('enablejsapi') > -1; 370 } 371 372 function isOriginAttrEnabled(url) { 373 return url.indexOf('origin') > -1; 374 } 375 376 // Returns key/value pairs of percentages: number of seconds to achieve 377 function getVideoCompletionMarks(duration) { 378 379 var marks = {}; 380 var points = [0, 10, 50, 90, 100]; 381 382 for (var i = 0; i < points.length; i++) { 383 384 var _point = points[i]; 385 var _mark = _point + '%'; 386 var _time = duration * _point / 100; 387 388 if (_point === 100) { 389 _time = _time - 1; 390 } 391 392 // 10% => 123 393 marks[_mark] = Math.floor(_time); 394 395 } 396 397 return marks; 398 399 } 400 401 // Determine if the element is a YouTube video or not 402 function tagIsYouTubeVideo(tag) { 403 var src = tag.src || ''; 404 return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1; 405 } 406 407 function tagIsYouTubeAsyncVideo(tag) { 408 if(tag.src && tag.src.indexOf("data:image") !== -1) return false; // video is loaded 409 var keys = Object.keys(tag.dataset); 410 for(var i = 0;i<keys.length;i++) { 411 if(keys[i].toLowerCase().indexOf("src") > -1) { 412 var src = tag.dataset[keys[i]]; 413 return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1; 414 } 415 } 416 return false; //not find src 417 } 418 419 // Turn embed objects into iframe objects and ensure they have the right parameters 420 function normalizeYouTubeIframe(tag) { 421 422 var loc = window.location; 423 var a = document.createElement('a'); 424 a.href = tag.src; 425 a.hostname = 'www.youtube.com'; 426 a.protocol = loc.protocol; 427 var tmpPathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname; // IE10 shim 428 429 if (!isJSApiAttrEnabled(a.search)) { 430 a.search = (a.search.length > 0 ? a.search + '&' : '') + 'enablejsapi=1'; 431 } 432 433 // for security reasons, YouTube wants an origin parameter set that matches our hostname
434 if (!isOriginAttrEnabled(a.search) && loc.hostname.indexOf('localhost') === -1) { 435 436 var port = loc.port ? ':' + loc.port : ''; 437 var origin = loc.protocol + '%2F%2F' + loc.hostname + port; 438 439 a.search = a.search + '&origin=' + origin; 440 441 } 442 443 if (tag.type === 'application/x-shockwave-flash') { 444 445 var newIframe = document.createElement('iframe'); 446 newIframe.height = tag.height; 447 newIframe.width = tag.width; 448 tmpPathname = tmpPathname.replace('/v/', '/embed/'); 449 450 tag.parentNode.parentNode.replaceChild(newIframe, tag.parentNode); 451 452 tag = newIframe; 453 454 } 455 456 a.pathname = tmpPathname; 457 458 if (tag.src !== a.href + a.hash) { 459 tag.src = a.href + a.hash; 460 } 461 462 return tag; 463 464 } 465 466 // Add event handlers for events emitted by the YouTube API 467 function addYouTubeEvents(iframe) { 468 469 var player = YT.get(iframe.id); 470 if (!player) { 471 player = new YT.Player(iframe, {}); 472 } 473 474 if (typeof iframe.pauseFlag === 'undefined') { 475 476 iframe.pauseFlag = false; 477 player.addEventListener('onStateChange', function (evt) { 478 onYouTubePlayerStateChange(evt, iframe); 479 }); 480 481 } 482 483 } 484 485 function addDynYouTubeVideos(el) { 486 // We only bind to iFrames with a YouTube URL with the enablejsapi=1 and 487 // origin=<<hostname>> parameters 488 if (el.tagName === 'IFRAME' 489 && tagIsYouTubeVideo(el) 490 && isJSApiAttrEnabled(el.src) 491 && isOriginAttrEnabled(el.src)) 492 { 493 addYouTubeEvents(el); 494 } 495 } 496 497 // Event handler for events emitted from the YouTube API 498 function onYouTubePlayerStateChange(evt, iframe) { 499 500 var stateIndex = evt.data; 501 var player = evt.target; 502 var targetVideoUrl = player.getVideoUrl(); 503 var targetVideoId = targetVideoUrl.match(/[?&]v=([^&#]*)/)[1]; // Extract the ID 504 var playerState = player.getPlayerState(); 505 var marks = getVideoCompletionMarks(player.getDuration()); 506 507 iframe.playTracker = iframe.playTracker || {}; 508 509 if (playerState === YT.PlayerState.PLAYING && !iframe.timer) { 510 511 clearInterval(iframe.timer); 512 513 // check every second to see if we've hit any of our percentage viewed marks 514 iframe.timer = setInterval(function () { 515 checkYouTubeCompletion(player, marks, iframe.videoId); 516 }, 1000); 517 518 } else { 519 520 clearInterval(iframe.timer); 521 iframe.timer = false; 522 523 } 524 525 // playlist edge-case handler 526 if (stateIndex === YT.PlayerState.PLAYING) { 527 iframe.playTracker[targetVideoId] = true; 528 iframe.videoId = targetVideoId; 529 iframe.pauseFlag = false; 530 } 531 532 if (!iframe.playTracker[iframe.videoId]) { 533 return false; // this video hasn't started yet, so this is spam 534 } 535 536 if (stateIndex === YT.PlayerState.PAUSED) { 537 538 if (!iframe.pauseFlag) { 539 iframe.pauseFlag = true; 540 } else { 541 return false; // we don't want to fire consecutive pause events 542 } 543 544 } 545 546 } 547 548 // Trigger event if YouTube video mark was reached 549 function checkYouTubeCompletion(player, marks, videoId) { 550 551 var currentTime = player.getCurrentTime(); 552 553 player[videoId] = player[videoId] || {}; 554 555 for (var key in marks) { 556 557 if (marks[key] <= currentTime && !player[videoId][key]) { 558 player[videoId][key] = true; 559 560 var data = player.getVideoData(); 561 562 if (key === '0%') { 563 key = 'play'; 564 } 565 566 var params = { 567 video_type: 'youtube', 568 video_id: videoId, 569 video_title: data.title, 570 }; 571 572 let disable_watch_video = []; 573 574 //Custom 575 if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) { 576 Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
577 triggers.forEach( function ( trigger ) { 578 if ( trigger.type === 'youtube' && trigger.rule === videoId ) { 579 580 let pixels = Object.keys( options.triggerEvents[ trigger_id ] ); 581 for ( let i = 0; i < pixels.length; i++ ) { 582 let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] ); 583 584 if ( trigger.disable_watch_video ) { 585 disable_watch_video.push( pixels[ i ] ); 586 } 587 588 if ( currentTime >= marks[ trigger.value ] ) { 589 if (pixels[i] !== 'reddit') { 590 event.params["progress"] = key; 591 Utils.copyProperties( params, event.params ); 592 } 593 594 if ( event.fired !== true ) { 595 if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) { 596 event = Utils.getFormFilledData( event ); 597 getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event ); 598 options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true; 599 } 600 } 601 } 602 } 603 } 604 } ) 605 } ) 606 } 607 608 // Auto 609 if( options.automatic.enable_video 610 && options.automatic.enable_youtube 611 && options.dynamicEvents.hasOwnProperty("automatic_event_video") 612 ) { 613 var pixels = Object.keys(options.dynamicEvents.automatic_event_video); 614 615 for (var i = 0; i < pixels.length; i++) { 616 if ( disable_watch_video.includes( pixels[ i ] ) ) { 617 continue; 618 } 619 var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]); 620 621 if ( pixels[ i ] !== 'reddit' ) { 622 event.params[ "progress" ] = key; 623 Utils.copyProperties(params, event.params) 624 } 625 626 if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) { 627 var time_trigger = event.automatic_event_video_trigger; 628 if ( currentTime >= marks[time_trigger] && event.fired !== true ) { 629 getPixelBySlag(pixels[i]).onWatchVideo(event); 630 631 //tiktok and reddit watch video fire once 632 options.dynamicEvents.automatic_event_video[pixels[i]].fired = true; 633 } 634 } else { 635 Utils.copyProperties(Utils.getRequestParam
635s(), event.params); 636 getPixelBySlag(pixels[i]).onWatchVideo(event); 637 } 638 } 639 } 640 641 if(key == "play") { 642 643 $.each(options.triggerEventTypes, function (triggerType, events) { 644 $.each(events, function (eventId, triggers) { 645 switch (triggerType) { 646 case 'video_play': 647 Utils.fireTriggerEvent(eventId); 648 break; 649 } 650 651 }); 652 }); 653 } 654 655 } 656 657 } 658 659 } 660 661 // Determine if the element is a Vimeo video or not 662 function tagIsVimeoVideo(tag) { 663 var src = tag.src || ''; 664 return src.indexOf('player.vimeo.com/video/') > -1; 665 } 666 667 function tagIsAsincVimeoVideo(tag) { 668 if(tag.src) return false; // video is loaded 669 var keys = Object.keys(tag.dataset); 670 for(var i = 0;i<keys.length;i++) { 671 if(keys[i].toLowerCase().indexOf("src") > -1) { 672 var src = tag.dataset[keys[i]]; 673 return src.indexOf('player.vimeo.com/video/') > -1; 674 } 675 } 676 return false; //not find src 677 } 678 679 function attachVimeoPlayerToTag(tag) { 680 var player = new Vimeo.Player(tag); 681 682 player.getDuration().then(function (pl,seconds) { 683 pl.pysMarks = getVideoCompletionMarks(seconds); 684 }.bind(null,player)); 685 686 player.getVideoTitle().then(function (pl,title) { 687 pl.pysVideoTitle = title; 688 }.bind(null,player)); 689 690 player.getVideoId().then(function (pl,id) { 691 pl.pysVideoId = id; 692 }.bind(null,player)); 693 694 player.pysCompletedMarks = {}; 695 696 player.on('play', function () { 697 698 if (this.pysTimer) { 699 return; 700 } 701 702 clearInterval(this.pysTimer); 703 704 var player = this; 705 706 this.pysTimer = setInterval(function () { 707 checkVimeoCompletion(player); 708 }, 1000); 709 710 }); 711 712 player.on('pause', function () { 713 clearInterval(this.pysTimer); 714 this.pysTimer = false; 715 }); 716 717 player.on('ended', function () { 718 clearInterval(this.pysTimer); 719 this.pysTimer = false; 720 }); 721 } 722 723 // Trigger event if Vimeo video mark was reached 724 function checkVimeoCompletion(player) { 725 726 player.getCurrentTime().then(function (seconds) { 727 728 for (var key in player.pysMarks) { 729 730 if (player.pysMarks[key] <= seconds && !player.pysCompletedMarks[key]) { 731 732 player.pysCompletedMarks[key] = true; 733 734 if (key === '0%') { 735 key = 'play'; 736 } 737 738 var params = { 739 video_type: 'vimeo', 740 video_id: player.pysVideoId, 741 video_title: player.pysVideoTitle, 742 }; 743 744 let disable_watch_video = []; 745 746 //Custom 747 if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) { 748 Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) { 749 triggers.forEach( function ( trigger ) { 750 if ( trigger.type === 'vimeo' && trigger.rule == player.pysVideoId ) { 751 let pixels = Object.keys( options.triggerEvents[ trigger_id ] ); 752 for ( let i = 0; i < pixels.length; i++ ) { 753 let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] ); 754 755 if ( trigger.disable_watch_video ) { 756 disable_watch_video.push( pixels[ i ] ); 757 } 758 759 if ( seconds >= player.pysMarks[ trigger.value ] ) { 760 if ( pixels[ i ] !== 'reddit' ) {
761 event.params[ "progress" ] = key; 762 Utils.copyProperties( params, event.params ); 763 } 764 765 if ( event.fired !== true ) { 766 if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) { 767 event = Utils.getFormFilledData( event ); 768 getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event ); 769 options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true; 770 } 771 } 772 } 773 } 774 } 775 } ) 776 } ) 777 } 778 779 // Auto 780 if(options.automatic.enable_video 781 && options.automatic.enable_vimeo 782 && options.dynamicEvents.hasOwnProperty("automatic_event_video") 783 ) { 784 var pixels = Object.keys(options.dynamicEvents.automatic_event_video); 785 786 for (var i = 0; i < pixels.length; i++) { 787 if ( disable_watch_video.includes( pixels[ i ] ) ) { 788 continue; 789 } 790 791 var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]); 792 793 if ( pixels[i] !== 'reddit' ) { 794 event.params["progress"] = key; 795 Utils.copyProperties(params, event.params); 796 } 797 798 if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) { 799 var time_trigger = event.automatic_event_video_trigger; 800 if ( seconds >= player.pysMarks[time_trigger] && event.fired !== true ) { 801 getPixelBySlag(pixels[i]).onWatchVideo(event); 802 803 //tiktok and reddit watch video fire once 804 options.dynamicEvents.automatic_event_video[pixels[i]].fired = true; 805 } 806 } else { 807 Utils.copyProperties(Utils.getRequestParam
807s(), event.params); 808 getPixelBySlag(pixels[i]).onWatchVideo(event); 809 } 810 } 811 } 812 813 if(key == "play") { 814 $.each(options.triggerEventTypes, function (triggerType, events) { 815 $.each(events, function (eventId, triggers) { 816 switch (triggerType) { 817 case 'video_play': 818 Utils.fireTriggerEvent(eventId); 819 break; 820 } 821 822 }); 823 }); 824 } 825 } 826 827 } 828 829 }); 830 831 } 832 833 /** 834 * COOKIES UTILS 835 */ 836 837 var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content' ,'utm_term']; 838 var utmId = ['fbadid', 'gadid', 'padid', 'bingid']; 839 var requestParams = []; 840 841 842 function getDomain(url) { 843 844 url = url.replace(/(https?:\/\/)?(www.)?/i, ''); 845 846 if (url.indexOf('/') !== -1) { 847 return url.split('/')[0]; 848 } 849 850 return url; 851 } 852 853 function checkSession() { 854 855 if( Cookies.get('pys_start_session') === undefined || 856 Cookies.get('pys_session_limit') === undefined) { 857 firstVisit = true; 858 return true 859 } 860 return false 861 862 } 863 864 function getTrafficSource() { 865 866 try { 867 868 let referrer = document.referrer.toString(), 869 source; 870 871 let direct = referrer.length === 0; 872 let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0; 873 let external = !direct && !internal; 874 875 if (external === false) { 876 source = 'direct'; 877 } else { 878 source = referrer; 879 } 880 881 if (source !== 'direct') { 882 // leave only domain (Issue #70) 883 return getDomain(source); 884 } else { 885 return source; 886 } 887 888 } catch (e) { 889 console.error(e); 890 return 'direct'; 891 } 892 893 } 894 895 /** 896 * Return query variables object with where property name is query variable 897 * and property value is query variable value. 898 */ 899 function getQueryVars() { 900 901 try { 902 903 var result = {}, 904 tmp = []; 905 906 window.location.search 907 .substr(1) 908 .split("&") 909 .forEach(function (item) { 910 911 tmp = item.split('='); 912 913 if (tmp.length > 1) { 914 result[tmp[0]] = tmp[1]; 915 } 916 917 }); 918 919 return result; 920 921 } catch (e) { 922 console.error(e); 923 return {}; 924 } 925 926 } 927 928 function getLandingPageValue() { 929 let name = "pys_landing_page" 930 if(options.visit_data_model === "last_visit") { 931 name = "last_pys_landing_page" 932 } 933 if(Cookies.get(name) && Cookies.get(name) !== "undefined") { 934 return Cookies.get(name); 935 } 936 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){ 937 return options.tracking_analytics.TrafficLanding; 938 } else{ 939 return ""; 940 } 941 } 942 function getTrafficSourceValue() { 943 let name = "pysTrafficSource" 944 if(options.visit_data_model === "last_visit") { 945 name = "last_pysTrafficSource" 946 } 947 if(Cookies.get(name) && Cookies.get(name) !== "undefined") { 948 return Cookies.get(name); 949 } 950 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficSource){ 951 return options.tracking_analytics.TrafficSource; 952 } else{ 953 return ""; 954 } 955 } 956 957 /** 958 * Handle alternative GCLID parameter for Safari compatibility 959 * Creates _gcl_aw cookie when alternative parameter is detected and _gcl_aw doesn't exist 960 */ 961 function handleAlternativeGclid() { 962 // Check if alternative GCLID is enabled 963 if (!options.GATags || !options.GATags.gclid_alternative_enabled || !options.GATags.gclid_alternative_param) { 964 return; 965 } 966 967 // GDPR consent checks - stop if any consent filter blocks it 968 if (options.gdpr.all_disabled_by_api) { 969 return; 970 } 971 if (options.gdpr.analytics_disabled_by_api) { 972 return; 973 } 974 if (options.cookie.disabled_all_cookie) { 975 return; 976 } 977 if (options.cookie.disabled_google_alternative_id) { 978 return; 979 } 980 981 const alternativeParam = options.GATags.gclid_alternative_param; 982 const queryVars = getQueryVars(); 983 984 // Check if alternative parameter exists in URL 985 if (queryVars[alternativeParam]) { 986 const gclidValue = queryVars[alternativeParam]; 987 988 // Only create _gcl_aw cookie if it doesn't exist 989 if (!Cookies.get('_gcl_aw')) { 990 // Create _gcl_aw cookie with the alternative parameter value in Google's format 991 // Format: GCL.{timestamp}.{gclid_value} 992 const timestamp = Math.floor(Date.now() / 1000); 993 const cookieValue = 'GCL.' + timestamp + '.' + gclidValue; 994 995 // Set cookie for 90 days (Google's standard) 996 const expires = new Date(); 997 expires.setTime(expires.getTime() + (90 * 24 * 60 * 60 * 1000)); 998 999 Cookies.set('_gcl_aw', cookieValue, { 1000 expires: expires, 1001 path: '/', 1002 domain: domain 1003 }); 1004 1005 if (options.debug) { 1006 console.log('PYS: Created _gcl_aw cookie from alternative parameter:', alternativeParam, '=', gclidValue); 1007 } 1008 } 1009 } 1010 } 1011 1012 function getUTMId(useLast = false) { 1013 try { 1014 let cookiePrefix = 'pys_' 1015 let terms = []; 1016 if (useLast) { 1017 cookiePrefix = 'last_pys_' 1018 } 1019 $.each(utmId, function (index, name) { 1020 if (Cookies.get(cookiePrefix + name)) { 1021 terms[name] = Cookies.get(cookiePrefix + name) 1022 } 1023 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) { 1024 terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name]) 1025 } 1026 }); 1027 return terms; 1028 } catch (e) { 1029 console.error(e); 1030 return []; 1031 } 1032 } 1033 /** 1034 * Return UTM terms from request query variables or from cookies. 1035 */ 1036 function getUTMs(useLast = false) { 1037 1038 try { 1039 let cookiePrefix = 'pys_' 1040 if(useLast) { 1041 cookiePrefix = 'last_pys_' 1042 } 1043 let terms = []; 1044 $.each(utmTerms, function (index, name) { 1045 if (Cookies.get(cookiePrefix + name)) { 1046 let value = Cookies.get(cookiePrefix + name); 1047 terms[name] = filterEmails(value); // do not allow email in request params (Issue #70) 1048 } 1049 else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) { 1050 terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name]) 1051 } 1052 }); 1053 1054 return terms; 1055 1056 } catch (e) { 1057 console.error(e); 1058 return []; 1059 } 1060 1061 } 1062 1063 function getDateTime() { 1064 var dateTime = new Array(); 1065 var date = new Date(), 1066 days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 1067 months = ['January', 'February', 'March', 'April', 'May', 'June', 1068 'July', 'August', 'September', 'October', 'November', 'December' 1069 ], 1070 hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08', 1071 '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17', 1072 '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24' 1073 ]; 1074 dateTime.push(hours[date.getHours()]); 1075 dateTime.push(days[date.getDay()]); 1076 dateTime.push(months[date.getMonth()]); 1077 return dateTime; 1078 } 1079 1080 function filterEmails(value) { 1081 return Utils.validateEmail(value) ? undefined : value; 1082 } 1083 1084 /** 1085 * PUBLIC API 1086 */ 1087 return { 1088 1089 PRODUCT_SIMPLE : 0, 1090 PRODUCT_VARIABLE : 1, 1091 PRODUCT_BUNDLE : 2, 1092 PRODUCT_GROUPED : 3, 1093 utmTerms : utmTerms, 1094 utmId : utmId, 1095 isNewSession: checkSession(), 1096 setHidePixelCookie: function(){ 1097 let refresh_after_consent = false; 1098 if ( !firstVisit && options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent) { 1099 refresh_after_consent = true; 1100 } 1101 if( !refresh_after_consent && !firstVisit) return false; 1102 1103 const url_parts = window.location.href; 1104 const url_params = new URLSearchParams(window.location.search); 1105 const matchingPixels = ["facebook", "ga", "gtm", "google_ads", "bing", "pinterest", "tiktok", "reddit"]; 1106 $.each(matchingPixels, function (index, slug) { 1107 var module = getPixelBySlag(slug); 1108 if (module && module.isEnabled()) { 1109 const fullUrl = window.location.href; 1110 $.each(module.getHidePixel(), function (index, hide_info) { 1111 for (const item of hide_info.hide_tag_contain) { 1112 if (item && fullUrl.includes(item)) { 1113 let hideTagTimeInMilliseconds = hide_info.hide_tag_time * 60 * 60 * 1000; 1114 let expiresTime = new Date().getTime() + hideTagTimeInMilliseconds; 1115 Cookies.set('hide_tag_' + hide_info.pixel, true, { expires: new Date(expiresTime), path: '/' });
1116 break; 1117 } 1118 } 1119 }); 1120 } 1121 1122 }); 1123 }, 1124 hideMatchingPixel: function(pixelValue, slug) { 1125 if(Cookies.get('hide_tag_'+pixelValue)) 1126 { 1127 return true; 1128 } 1129 return false; 1130 }, 1131 validateEmail: function (email) { 1132 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,}))$/; 1133 return re.test(email); 1134 }, 1135 fireEventForAllPixel:function(functionName,events){ 1136 if (events.hasOwnProperty(Facebook.tag())) 1137 Facebook[functionName](events[Facebook.tag()]); 1138 if (events.hasOwnProperty(Analytics.tag())) 1139 Analytics[functionName](events[Analytics.tag()]); 1140 if (events.hasOwnProperty(GAds.tag())) 1141 GAds[functionName](events[GAds.tag()]); 1142 if (events.hasOwnProperty(Pinterest.tag())) 1143 Pinterest[functionName](events[Pinterest.tag()]); 1144 if (events.hasOwnProperty(Bing.tag())) 1145 Bing[functionName](events[Bing.tag()]); 1146 if (events.hasOwnProperty(TikTok.tag())) 1147 TikTok[functionName](events[TikTok.tag()]); 1148 if (events.hasOwnProperty(Reddit.tag())) 1149 Reddit[functionName](events[Reddit.tag()]); 1150 1151 if (events.hasOwnProperty(GTM.tag())) 1152 GTM[functionName](events[GTM.tag()]); 1153 }, 1154 1155 getQueryValue:function (name){ 1156 return getQueryVars()[name]; 1157 }, 1158 1159 filterEmails: function (value) { 1160 return filterEmails(value); 1161 }, 1162 1163 setupPinterestObject: function () { 1164 Pinterest = window.pys.Pinterest || Pinterest; 1165 return Pinterest; 1166 }, 1167 1168 setupBingObject: function () { 1169 Bing = window.pys.Bing || Bing; 1170 return Bing; 1171 }, 1172 1173 setupRedditObject: function () { 1174 Reddit = window.pys.Reddit || Reddit; 1175 return Reddit; 1176 }, 1177 1178 // Clone all object members to another and return it 1179 copyProperties: function (from, to) { 1180 for (var key in from) { 1181 if("function" == typeof from[key]) { 1182 continue; 1183 } 1184 to[key] = from[key]; 1185 } 1186 return to; 1187 }, 1188 1189 /** 1190 * Generate unique ID 1191 */ 1192 generateUniqueId : function (event) { 1193 if(event.eventID.length == 0 || 1194 (!event.isVariationTrigger && 1195 (event.type == "static" && options.ajaxForServerStaticEvent || 1196 event.type !== "static" && options.ajaxForServerEvent) 1197 ) 1198 ) { 1199 let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id; 1200 if (!uniqueId.hasOwnProperty(idKey)) { 1201 uniqueId[idKey] = pys_generate_token(); 1202 } 1203 return uniqueId[idKey]; 1204 } 1205 else if(event.eventID.length !== 0) 1206 { 1207 return event.eventID; 1208 } 1209 }, 1210 1211 // Flatten object for sendBeacon compatibility 1212 flattenObject: function (obj, prefix = '', res = {}) { 1213 for (const [key, value] of Object.entries(obj)) { 1214 const prefixedKey = prefix 1215 ? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
1216 : key; 1217 if (value !== null && typeof value === 'object' && !(value instanceof File)) { 1218 this.flattenObject(value, prefixedKey, res); 1219 } else { 1220 res[prefixedKey] = value; 1221 } 1222 } 1223 return res; 1224 }, 1225 1226 sendServerAjaxRequest: function ( url, data ) { 1227 // Check if we should use REST API for TikTok or Facebook 1228 if (data.action === 'pys_tiktok_api_event' && window.pysTikTokRest) { 1229 // Use TikTok REST API 1230 this.sendRestAPIRequest(data, 'tiktok'); 1231 return; 1232 } 1233 1234 if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) { 1235 // Use Facebook REST API 1236 this.sendRestAPIRequest(data, 'facebook'); 1237 return; 1238 } 1239 1240 // Check if sendBeacon is enabled and supported 1241 if (options.useSendBeacon && navigator.sendBeacon) { 1242 try { 1243 // Flatten the data object for sendBeacon compatibility 1244 const flattenedData = this.flattenObject(data); 1245 const formData = new URLSearchParams(); 1246 1247 // Convert flattened data to URLSearchParams 1248 for (const [key, value] of Object.entries(flattenedData)) { 1249 if (value !== null && value !== undefined) { 1250 formData.append(key, value); 1251 } 1252 } 1253 1254 // Try to send using sendBeacon 1255 const success = navigator.sendBeacon(url, formData); 1256 if (success) { 1257 return; // Successfully sent via sendBeacon 1258 } 1259 } catch (e) { 1260 // If sendBeacon fails, fall back to jQuery.ajax 1261 if (options.debug) { 1262 console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e); 1263 } 1264 } 1265 } 1266 1267 // Fallback to jQuery.ajax 1268 jQuery.ajax( { 1269 type: 'POST', 1270 url: url, 1271 data: data, 1272 headers: { 1273 'Cache-Control': 'no-cache' 1274 }, 1275 success: function () { 1276 }, 1277 } ); 1278 }, 1279 1280 // Send event via REST API (unified function for TikTok, Facebook, and other platforms) 1281 // Replaces the old sendTikTokRestAPIRequest and sendFacebookRestAPIRequest functions 1282 sendRestAPIRequest: function (data, platform) { 1283 let restApiUrl; 1284 1285 // Get platform-specific REST API configuration 1286 switch (platform) { 1287 case 'tiktok': 1288 restApiUrl = window.pysTikTokRest ? window.pysTikTokRest.restApiUrl : '/wp-json/pys-tiktok/v1/event'; 1289 break; 1290 case 'facebook': 1291 restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event'; 1292 break; 1293 case 'pinterest': 1294 restApiUrl = window.pysPinterestRest ? window.pysPinterestRest.restApiUrl : '/wp-json/pys-pinterest/v1/event'; 1295 break; 1296 default: 1297 console.error('PYS: Unknown platform for REST API:', platform); 1298 this.sendAjaxFallback(data); 1299 return; 1300 } 1301 1302 // Prepare data for REST API 1303 const restApiData = { 1304 event: data.event, 1305 event_slug: data.event_slug, 1306 data: JSON.stringify(data.data || {}), 1307 ids: JSON.stringify(data.ids || []), 1308 eventID: data.event_id || data.eventID || '',
1309 woo_order: data.woo_order || '0', 1310 edd_order: data.edd_order || '0' 1311 }; 1312 1313 // Try to send using sendBeacon first (if enabled) 1314 if (options.useSendBeacon && navigator.sendBeacon) { 1315 try { 1316 const formData = new URLSearchParams(); 1317 for (const [key, value] of Object.entries(restApiData)) { 1318 formData.append(key, value); 1319 } 1320 1321 if (navigator.sendBeacon(restApiUrl, formData)) { 1322 return; 1323 } 1324 } catch (e) { 1325 // sendBeacon failed, continue to fetch 1326 } 1327 } 1328 1329 // Try to send using fetch with REST API 1330 if (window.fetch) { 1331 const headers = { 1332 'Content-Type': 'application/json' 1333 }; 1334 1335 fetch(restApiUrl, { 1336 method: 'POST', 1337 headers: headers, 1338 body: JSON.stringify(restApiData) 1339 }) 1340 .then(response => { 1341 if (!response.ok) { 1342 throw new Error(platform + ' REST API request failed: ' + response.status); 1343 } 1344 }) 1345 .catch(error => { 1346 // Fallback to AJAX if REST API fails 1347 if (options.debug) { 1348 console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error); 1349 } 1350 this.sendAjaxFallback(data); 1351 }); 1352 } else { 1353 // Fallback to AJAX if fetch is not supported 1354 this.sendAjaxFallback(data); 1355 } 1356 }, 1357 1358 1359 1360 // Fallback AJAX method 1361 sendAjaxFallback: function (data) { 1362 jQuery.ajax({ 1363 type: 'POST', 1364 url: options.ajaxUrl, 1365 data: data, 1366 headers: { 1367 'Cache-Control': 'no-cache' 1368 }, 1369 success: function () { 1370 }, 1371 }); 1372 }, 1373 1374 clone: function(obj) { 1375 var copy; 1376 1377 // Handle the 3 simple types, and null or undefined 1378 if (null == obj || "object" != typeof obj) return obj; 1379 1380 // Handle Date 1381 if (obj instanceof Date) { 1382 copy = new Date(); 1383 copy.setTime(obj.getTime()); 1384 return copy; 1385 } 1386 1387 // Handle Array 1388 if (obj instanceof Array) { 1389 copy = []; 1390 for (var i = 0, len = obj.length; i < len; i++) { 1391 if("function" == typeof obj[i]) { 1392 continue; 1393 } 1394 copy[i] = Utils.clone(obj[i]); 1395 } 1396 return copy; 1397 } 1398 1399 // Handle Object 1400 if (obj instanceof Object) { 1401 copy = {}; 1402 for (var attr in obj) { 1403 if (obj.hasOwnProperty(attr)) { 1404 if("function" == typeof obj[attr]) { 1405 continue; 1406 } 1407 copy[attr] = Utils.clone(obj[attr]); 1408 } 1409 } 1410 return copy; 1411 } 1412 1413 return obj; 1414 }, 1415 1416 // Returns array of elements with given tag name 1417 getTagsAsArray: function (tag) { 1418 return [].slice.call(document.getElementsByTagName(tag)); 1419 }, 1420 1421 1422 initializeVideoAPIs: function (options) { 1423 let trigger_has_video_YT, trigger_has_video_Vimeo = false; 1424 if (options.hasOwnProperty('automatic') && options.automatic.enable_video) { 1425 if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) { 1426 Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
1427 triggers.forEach( function ( trigger ) { 1428 if (trigger.type === 'youtube') { 1429 trigger_has_video_YT = true; 1430 } 1431 if(trigger.type === 'vimeo'){ 1432 trigger_has_video_Vimeo = true; 1433 } 1434 }); 1435 }); 1436 } 1437 if ( 1438 options.hasOwnProperty('enable_automatic_events') && 1439 options.enable_automatic_events 1440 ) { 1441 if (options.automatic.enable_youtube || trigger_has_video_YT) { 1442 Utils.initYouTubeAPI(); 1443 } 1444 if (options.automatic.enable_vimeo || trigger_has_video_Vimeo) { 1445 Utils.initVimeoAPI(); 1446 } 1447 } 1448 } 1449 }, 1450 /** 1451 * Load and initialize YouTube API 1452 * 1453 * @link: https://developers.google.com/youtube/iframe_api_reference 1454 */ 1455 initYouTubeAPI: function () { 1456 1457 // maybe load YouTube JS API 1458 if (typeof window.YT === 'undefined') { 1459 var tag = document.createElement('script'); 1460 tag.src = '//www.youtube.com/iframe_api'; 1461 var firstScriptTag = document.getElementsByTagName('script')[0]; 1462 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 1463 } 1464 1465 // initialize when API is ready 1466 if ( typeof window.onYouTubeIframeAPIReady !== 'function' ) { 1467 1468 window.onYouTubeIframeAPIReady = function () { 1469 1470 // collect all possible YouTube tags 1471 var potentialVideos = Utils.getTagsAsArray( 'iframe' ).concat(
1471Utils.getTagsAsArray( 'embed' ) ); 1472 1473 // turn videos into trackable videos with events 1474 for ( var i = 0; i < potentialVideos.length; i++ ) { 1475 var video = potentialVideos[ i ]; 1476 if ( tagIsYouTubeVideo( video ) ) { 1477 var iframe = normalizeYouTubeIframe( video ); 1478 addYouTubeEvents( iframe ); 1479 } else if ( tagIsYouTubeAsyncVideo( video ) ){ 1480 video.addEventListener( "load", function ( evt ) { 1481 var iframe = normalizeYouTubeIframe( evt.currentTarget ); 1482 addYouTubeEvents( iframe ); 1483 } ); 1484 } 1485 } 1486 1487 var targets = document.querySelectorAll( '.elementor-widget-video .elementor-wrapper' ); 1488 1489 const config = { 1490 attributes: false, 1491 childList: true, 1492 subtree: true 1493 }; 1494 1495 const callback = function ( mutationsList, observer ) { 1496 for ( let mutation of mutationsList ) { 1497 if ( mutation.type === 'childList' ) { 1498 for ( var m = 0; m < mutation.addedNodes.length; m++ ) { 1499 addDynYouTubeVideos( mutation.addedNodes[ m ] ); 1500 } 1501 } 1502 } 1503 }; 1504 // observe elementator widget-video and add event when it add iframe 1505 for ( var i = 0; i < targets.length; i++ ) { 1506 const observer = new MutationObserver( callback ); 1507 observer.observe( targets[ i ], config );//maybe remove before add 1508 } 1509 } 1510 } 1511 }, 1512 1513 /** 1514 * Load and initialize Vimeo API 1515 * 1516 * @link: https://github.com/vimeo/player.js 1517 */ 1518 initVimeoAPI: function () { 1519 1520 1521 $(document).ready(function () { 1522 1523 var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed')); 1524 1525 for (var i = 0; i < potentialVideos.length; i++) { 1526 var tag = potentialVideos[i]; 1527 if (tagIsVimeoVideo(tag)) { 1528 var nextElementHasClass = $(tag).closest('.elementor-widget-video').find('.elementor-custom-embed-image-overlay'); 1529 if(nextElementHasClass.length > 0) { 1530 tag.addEventListener("load", function() { 1531 attachVimeoPlayerToTag(this); 1532 }); 1533 } 1534 else { 1535 attachVimeoPlayerToTag(tag); 1536 } 1537 1538 1539 } else { 1540 if (tagIsAsincVimeoVideo(tag)) { 1541 tag.addEventListener("load", function(evt) { 1542 attachVimeoPlayerToTag(evt.currentTarget); 1543 }); 1544 } 1545 } 1546 } 1547 1548 }); 1549 1550 }, 1551 1552 manageCookies: function () { 1553 // Handle alternative GCLID parameter for Safari compatibility 1554 handleAlternativeGclid(); 1555 1556 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 1557 if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) { 1558 return; 1559 } 1560 } 1561 1562 let cm_consent_not_expressed = false; 1563 if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) { 1564 if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) { 1565 cm_consent_not_expressed = true; 1566 } 1567 } 1568 1569 if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) { 1570 let duration = options.last_visit_duration * 60000 1571 var now = new Date(); 1572 now.setTime(now.getTime() + duration); 1573 Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain }) 1574 Cookies.set('pys_start_session', true,{ path: '/',domain: domain }); 1575 Utils.setHidePixelCookie(); 1576 } 1577 1578 if (!Cookies.get('pbid') && Facebook.isEnabled() && options.ajaxForServerEvent) { 1579 jQuery.ajax({ 1580 url: options.ajaxUrl, 1581 dataType: 'json', 1582 data: { 1583 action: 'pys_get_pbid' 1584 }, 1585 success: function (res) { 1586 if (res.data && res.data.pbid != false && options.send_external_id) { 1587 if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){ 1588 var expires = parseInt(options.external_id_expire || 180); 1589 Cookies.set('pbid', res.data.pbid, { expires: expires,path: '/',domain: domain }); 1590 } 1591 1592 if(options.hasOwnProperty('facebook')) { 1593 options.facebook.advancedMatching = { 1594 ...options.facebook.advancedMatching, // ÑаÑпÑлÑем ÑекÑÑие знаÑÐµÐ½Ð¸Ñ advancedMatching 1595 external_id: res.data.pbid 1596 }; 1597 } 1598 } 1599 } 1600 }); 1601 } else if (Cookies.get('pbid') && Facebook.isEnabled()){ 1602 if(options.hasOwnProperty('facebook')) { 1603 options.facebook.advancedMatching = { 1604 ...options.facebook.advancedMatching, 1605 external_id: Cookies.get('pbid') 1606 }; 1607 } 1608 } 1609 let expires = parseInt(options.cookie_duration); // days 1610 let queryVars = getQueryVars(); 1611 let landing = window.location.href.split('?')[0]; 1612 try { 1613 // save data for first visit 1614 if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) { 1615 1616 if(!options.cookie.disabled_first_visit_cookie) 1617 { 1618 Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain }); 1619 } 1620 else { 1621 Cookies.remove('pys_first_visit', { path: '/',domain: domain } ) 1622 } 1623 1624 if(!options.cookie.disabled_trafficsource_cookie) 1625 { 1626 Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain }); 1627 } 1628 else { 1629 Cookies.remove('pysTrafficSource', { path: '/',domain: domain }) 1630 } 1631 1632 if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param) 1633 { 1634 Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain }); 1635 } 1636 else { 1637 Cookies.remove('pys_landing_page', { path: '/',domain: domain }) 1638 } 1639 1640 if(!options.cookie.disabled_utmTerms_cookie) 1641 { 1642 $.each(utmTerms, function (index, name) { 1643 if (queryVars.hasOwnProperty(name)) { 1644 Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 1645 } else { 1646 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1647 } 1648 }); 1649 } 1650 else { 1651 $.each(utmTerms, function (index, name) { 1652 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1653 }); 1654 } 1655 1656 if(!options.cookie.disabled_utmId_cookie) 1657 { 1658 $.each(utmId,function(index,name) { 1659 if (queryVars.hasOwnProperty(name)) { 1660 Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 1661 } else { 1662 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1663 } 1664 }) 1665 } 1666 else { 1667 $.each(utmId, function (index, name) { 1668 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1669 }); 1670 } 1671 1672 } 1673 // save data for last visit if it new session 1674 if(isNewSession && (!options.cookie.disabled_all_cookie)) { 1675 if(!options.cookie.disabled_trafficsource_cookie) 1676 { 1677 Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain }); 1678 } 1679 else { 1680 Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain }) 1681 } 1682 1683 if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param) 1684 { 1685 Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain }); 1686 } 1687 else { 1688 Cookies.remove('last_pys_landing_page', { path: '/',domain: domain }) 1689 } 1690 1691 if(!options.cookie.disabled_utmTerms_cookie) 1692 { 1693 $.each(utmTerms, function (index, name) { 1694 if (queryVars.hasOwnProperty(name)) { 1695 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 1696 } 1697 }); 1698 } 1699 else { 1700 $.each(utmTerms, function (index, name) { 1701 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 1702 }); 1703 } 1704 1705 if(!options.cookie.disabled_utmId_cookie) 1706 { 1707 $.each(utmId,function(index,name) { 1708 if (queryVars.hasOwnProperty(name)) { 1709 Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain }); 1710 } 1711 }) 1712 } 1713 else { 1714 $.each(utmId, function (index, name) { 1715 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 1716 }); 1717 } 1718 1719 } 1720 if(options.cookie.disabled_start_session_cookie) { 1721 Cookies.remove('pys_start_session', { path: '/',domain: domain }) 1722 Cookies.remove('pys_session_limit', { path: '/',domain: domain }) 1723 } 1724 if(options.cookie.disabled_all_cookie) 1725 { 1726 Cookies.remove('pys_first_visit', { path: '/',domain: domain }) 1727 Cookies.remove('pysTrafficSource', { path: '/',domain: domain }) 1728 Cookies.remove('pys_landing_page', { path: '/',domain: domain }) 1729 Cookies.remove('last_pys_landing_page', { path: '/',domain: domain }) 1730 Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain }) 1731 Cookies.remove('pys_start_session', { path: '/',domain: domain }) 1732 Cookies.remove('pys_session_limit', { path: '/',domain: domain }) 1733 $.each(Utils.utmTerms, function (index, name) { 1734 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1735 }); 1736 $.each(Utils.utmId,function(index,name) { 1737 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 1738 }) 1739 $.each(Utils.utmTerms, function (index, name) { 1740 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 1741 }); 1742 $.each(Utils.utmId,function(index,name) { 1743 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 1744 }); 1745 } 1746 } catch (e) { 1747 console.error(e); 1748 } 1749 }, 1750
1751 initializeRequestParams: function () { 1752 1753 if (options.trackTrafficSource) { 1754 requestParams.traffic_source = getTrafficSourceValue(); 1755 } 1756 1757 if (options.trackUTMs) { 1758 1759 var utms = getUTMs(options.visit_data_model === "last_visit"); 1760 1761 $.each(utmTerms, function (index, term) { 1762 if (term in utms) { 1763 requestParams[term] = utms[term]; 1764 } 1765 }); 1766 1767 } 1768 1769 1770 var dateTime = getDateTime(); 1771 if(options.enable_event_time_param) { 1772 requestParams.event_hour = dateTime[0]; 1773 } 1774 1775 if(options.enable_event_day_param) { 1776 requestParams.event_day = dateTime[1]; 1777 } 1778 if(options.enable_event_month_param) { 1779 requestParams.event_month = dateTime[2]; 1780 } 1781 1782 if(options.enable_lading_page_param){ 1783 requestParams.landing_page = getLandingPageValue(); 1784 } 1785 }, 1786
1787 getRequestParams: function () { 1788 return requestParams; 1789 }, 1790 1791 /** 1792 * DOWNLOAD DOCS 1793 */ 1794 1795 getLinkExtension: function (link) { 1796 1797 // Remove anchor, query string and everything before last slash 1798 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1799 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1800 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1801 1802 // If there's a period left in the URL, then there's a extension 1803 if (link.length > 0 && link.indexOf('.') !== -1) { 1804 link = link.substring(link.lastIndexOf(".") + 1); // Remove everything but what's after the first period 1805 return link; 1806 } else { 1807 return ""; 1808 } 1809 }, 1810 1811 getLinkFilename: function (link) { 1812 1813 // Remove anchor, query string and everything before last slash 1814 link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#")); 1815 link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?")); 1816 link = link.substring(link.lastIndexOf("/") + 1, link.length); 1817 1818 // If there's a period left in the URL, then there's a extension 1819 if (link.length > 0 && link.indexOf('.') !== -1) { 1820 return link; 1821 } else { 1822 return ""; 1823 } 1824 }, 1825 1826 /** 1827 * CUSTOM EVENTS 1828 */ 1829 1830 setupMouseOverClickEvents: function (eventId, triggers) { 1831 1832 // Non-default binding used to avoid situations when some code in external js 1833 // stopping events propagation, eg. returns false, and our handler will never called 1834 document.addEventListener('mouseover', function(event) { 1835 var matchedElements = Array.from(document.querySelectorAll(triggers)); 1836 var clickedElement = event.target; 1837 var closestMatch = clickedElement.closest(triggers); 1838 if (matchedElements.includes(clickedElement) || closestMatch){ 1839 if (event.target.classList.contains('pys-mouse-over-' + eventId)) { 1840 return true; 1841 } else { 1842 event.target.classList.add('pys-mouse-over-' + eventId); 1843 } 1844 1845 Utils.fireTriggerEvent(eventId); 1846 } 1847 }); 1848 1849 1850 }, 1851 1852 setupFormFieldEvents: function (eventId, triggers) { 1853 triggers.forEach(function(trigger) { 1854 let eventType = 'input'; 1855 1856 if (['checkbox', 'radio', 'select'].includes(trigger.type)) { 1857 eventType = 'change'; 1858 } else if (['text', 'email', 'tel'].includes(trigger.type)) { 1859 eventType = 'blur'; 1860 } 1861 1862 const form = document.querySelector(trigger.form); 1863 if (!form) return; 1864 1865 const field = form.querySelector(trigger.field); // иÑем поле ТÐÐЬÐРвнÑÑÑи ÑоÑÐ¼Ñ 1866 if (!field) return; 1867 1868 field.addEventListener(eventType, function (event) { 1869 Utils.fireTriggerEvent(eventId); 1870 }, true); 1871 }); 1872 }, 1873 1874 setupCSSClickEvents: function (eventId, triggers) { 1875 // Non-default binding used to avoid situations when some code in external js 1876 // stopping events propagation, eg. returns false, and our handler will never called 1877 // add event to document to support dyn class 1878 document.addEventListener('click', function(event) { 1879 let matchedElements = Array.from(document.querySelectorAll(triggers)), 1880 clickedElement = event.target, 1881 closestMatch = clickedElement.closest(triggers); 1882 1883 if (matchedElements.includes(clickedElement) || closestMatch){ 1884 Utils.fireTriggerEvent(eventId); 1885 } 1886 }, true); 1887 }, 1888 1889 setupURLClickEvents: function () { 1890 1891 if( !options.triggerEventTypes.hasOwnProperty('url_click') ) { 1892 return; 1893 } 1894 // Non-default binding used to avoid situations when some code in external js 1895 // stopping events propagation, eg. returns false, and our handler will never called 1896 document.addEventListener('click', function(event) { 1897 let anchor = event.target.closest('a'); 1898 1899 if (anchor) { 1900 var url = anchor.getAttribute('href'); 1901 if (url) { 1902 Object.entries(options.triggerEventTypes.url_click).forEac
1902h(function ([eventId, triggers]) { 1903 triggers.forEach(function (trigger) { 1904 if (Utils.compareUrl(url, trigger.value, trigger.rule)) { 1905 Utils.fireTriggerEvent(eventId); 1906 } 1907 }); 1908 }); 1909 } 1910 } 1911 }, true); 1912 1913 }, 1914 1915 removeUrlDomain(url) { 1916 if(url.indexOf("/#") > -1) { 1917 url = url.substring(0, url.indexOf("/#")); 1918 } 1919 return url.replace('http://','') 1920 .replace('https://','') 1921 .replace('www.','') 1922 .trim() 1923 .replace(/^\/+/g, '') 1924 1925 }, 1926 1927 compareUrl: function(base,url,rule){ 1928 1929 if(url == "*" || url == '') return true; 1930 1931 base = Utils.removeUrlDomain(base) 1932 url = Utils.removeUrlDomain(url) 1933 1934 if(rule == 'match') { 1935 return url == base; 1936 } else { 1937 return base.indexOf(url) !== -1 1938 } 1939 1940 }, 1941 1942 setupScrollPosEvents: function (eventId, triggers) { 1943 1944 var scrollPosThresholds = {}, 1945 docHeight = $(document).height() - $(window).height(); 1946 1947 // convert % to absolute positions 1948 $.each(triggers, function (index, scrollPos) { 1949 1950 // convert % to pixels 1951 scrollPos = docHeight * scrollPos / 100; 1952 scrollPos = Math.round(scrollPos); 1953 1954 scrollPosThresholds[scrollPos] = eventId; 1955 1956 }); 1957 1958 $(document).on("scroll",function () { 1959 1960 var scrollPos = $(window).scrollTop(); 1961 1962 $.each(scrollPosThresholds, function (threshold, eventId) { 1963 1964 // position has not reached yes 1965 if (scrollPos <= threshold) { 1966 return true; 1967 } 1968 1969 // fire event only once 1970 if (eventId === null) { 1971 return true; 1972 } else { 1973 scrollPosThresholds[threshold] = null; 1974 } 1975 1976 Utils.fireTriggerEvent(eventId); 1977 1978 }); 1979 1980 }); 1981 1982 }, 1983 setupCommentEvents : function (eventId,triggers) { 1984 $('form.comment-form').on("submit",function () { 1985 Utils.fireTriggerEvent(eventId); 1986 }); 1987 }, 1988 1989 setupEmailLinkEvents: function ( events ) { 1990 1991 $( document ).on( 'click', 'a', function ( event ) { 1992 let anchor = event.target.closest('a'); 1993 1994 if (anchor) { 1995 let url = anchor.getAttribute('href'); 1996 if (url && (url.startsWith('mailto:') || url.startsWith('tel:'))) { 1997 1998 let sendEventIds = [], 1999 disabled_for_pixels = [], 2000 disabled_email_action = false; 2001 2002 $.each(events, function (eventId, trigger_group) { 2003 url = url.replace('mailto:', '').replace('tel:', ''); 2004 trigger_group.forEach(function (triggers) {
2005 triggers.rules.forEach(function (trigger) { 2006 if (Utils.compareUrl(url, trigger.value, trigger.rule)) { 2007 sendEventIds.push(eventId); 2008 if (triggers.hasOwnProperty('disabled_email_link') && triggers.disabled_email_link) { 2009 disabled_email_action = true; 2010 if (options.triggerEvents.hasOwnProperty(eventId)) { 2011 disabled_for_pixels.push(...Object.keys(options.triggerEvents[eventId])); 2012 } 2013 } 2014 } 2015 }); 2016 }) 2017 }) 2018 2019 if (sendEventIds.length > 0) { 2020 sendEventIds.forEach(function (sendEventId) { 2021 Utils.fireTriggerEvent(sendEventId); 2022 }) 2023 } 2024 setupEmailLinks(disabled_for_pixels); 2025 } 2026 } 2027 } ) 2028 }, 2029 2030 /** 2031 * Events 2032 */ 2033 2034 isEventInTimeWindow: function (eventName, event, prefix) { 2035 2036 if(event.hasOwnProperty("hasTimeWindow") && event.hasTimeWindow) { 2037 var cookieName = prefix+"_"+eventName; 2038 var now = new Date().getTime(); 2039 2040 if(Cookies.get(cookieName) !== undefined) { 2041 2042 var lastTimeFire = Cookies.get(cookieName); 2043 var fireTime = event.timeWindow * 60*60*1000; 2044 2045 if( now - lastTimeFire > fireTime) { 2046 Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} ); 2047 } else { 2048 return false; 2049 } 2050 } else { 2051 Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} ); 2052 } 2053 } 2054 return true 2055 }, 2056 2057 fireTriggerEvent: function (eventId) { 2058 2059 if (!options.triggerEvents.hasOwnProperty(eventId)) { 2060 return; 2061 } 2062 2063 var event = {}; 2064 var events = options.triggerEvents[eventId]; 2065 2066 if (events.hasOwnProperty('facebook')) { 2067 event = events.facebook; 2068 if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) { 2069 event = Utils.getFormFilledData(event); 2070 Facebook.fireEvent(event.name, event); 2071 } 2072 } 2073 2074 if (events.hasOwnProperty('ga')) { 2075 event = events.ga; 2076 if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) { 2077 event = Utils.getFormFilledData(event); 2078 Analytics.fireEvent(event.name, event); 2079 } 2080 } 2081 2082 if (events.hasOwnProperty('google_ads')) { 2083 event = events.google_ads; 2084 if(Utils.isEventInTimeWindow(event.name,event,"dyn_google_ads_"+eventId)) { 2085 event = Utils.getFormFilledData(event); 2086 GAds.fireEvent(event.name, event); 2087 } 2088 } 2089 2090 if (events.hasOwnProperty('pinterest')) { 2091 event = events.pinterest; 2092 if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) { 2093 event = Utils.getFormFilledData(event); 2094 Pinterest.fireEvent(event.name, event);; 2095 } 2096 } 2097 2098 if (events.hasOwnProperty('bing')) { 2099 event = events.bing;
2100 if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) { 2101 event = Utils.getFormFilledData(event); 2102 Bing.fireEvent(event.name, event);; 2103 } 2104 } 2105 if (events.hasOwnProperty('tiktok')) { 2106 event = events.tiktok; 2107 if(Utils.isEventInTimeWindow(event.name,event,"dyn_tiktok_"+eventId)) { 2108 event = Utils.getFormFilledData(event); 2109 TikTok.fireEvent(event.name, event); 2110 } 2111 } 2112 if (events.hasOwnProperty('reddit')) { 2113 event = events.reddit; 2114 if(Utils.isEventInTimeWindow(event.name,event,"dyn_reddit_"+eventId)) { 2115 event = Utils.getFormFilledData(event); 2116 Reddit.fireEvent(event.name, event); 2117 } 2118 } 2119 2120 2121 if (events.hasOwnProperty('gtm')) { 2122 event = events.gtm; 2123 if(Utils.isEventInTimeWindow(event.name,event,"dyn_gtm_"+eventId)) { 2124 event = Utils.getFormFilledData(event); 2125 GTM.fireEvent(event.name, event); 2126 } 2127 } 2128 2129 2130 }, 2131 2132 isFirstPurchaseFire: function ($eventName,orderId,pixel) { 2133 2134 if(Cookies.get("pys_"+$eventName+"_order_id_"+pixel) == orderId) { 2135 return false; 2136 } else { 2137 Cookies.set("pys_"+$eventName+"_order_id_"+pixel, orderId, { expires: 1,path: '/' }); 2138 } 2139 return true; 2140 }, 2141 2142 fireStaticEvents: function (pixel, timeout = 0) { 2143 2144 if (options.staticEvents.hasOwnProperty(pixel)) { 2145 2146 $.each(options.staticEvents[pixel], function (eventId, events) { 2147 2148 //skip purchase event if this order was fired 2149 if( options.woo.hasOwnProperty('woo_purchase_on_transaction') && 2150 options.woo.woo_purchase_on_transaction && 2151 (eventId === "woo_purchase" || eventId === "woo_purchase_category") ) { 2152 if(!Utils.isFirstPurchaseFire(eventId,events[0].woo_order,pixel)) { 2153 return; 2154 } 2155 } 2156 2157 if( options.edd.hasOwnProperty('edd_purchase_on_transaction') && 2158 options.edd.edd_purchase_on_transaction && 2159 (eventId === "edd_purchase" || eventId === "edd_purchase_category") ) { 2160 if(!Utils.isFirstPurchaseFire(eventId,events[0].edd_order,pixel)) { 2161 return; 2162 } 2163 } 2164 2165 2166 $.each(events, function (index, event) { 2167 2168 event.fired = event.fired || false; 2169 2170 if (!event.fired && Utils.isEventInTimeWindow(event.name,event,'static_' + pixel+"_")) { 2171 event = Utils.getFormFilledData(event); 2172 2173 var fired = false; 2174 2175 // fire event 2176 if ( pixel === 'tiktok' ) { 2177 setTimeout(function() { 2178 getPixelBySlag(pixel).fireEvent(event.name, event); 2179 }, timeout * 500); 2180 timeout++; 2181 } else { 2182 getPixelBySlag(pixel).fireEvent(event.name, event); 2183 } 2184 2185 // prevent event double event firing 2186 event.fired = fired; 2187 } 2188 }); 2189 }); 2190 } 2191 }, 2192 2193 /** 2194 * Load tag's JS 2195 * 2196 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/ 2197 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
2197s-mets 2198 */ 2199 loadGoogleTag: function (id) { 2200 2201 if (!gtag_loaded) { 2202 let dataLayerName = this.dataLayerName; 2203 if(options.hasOwnProperty('GATags')){ 2204 switch (options.GATags.ga_datalayer_type) { 2205 case 'default': 2206 dataLayerName = 'dataLayerPYS'; 2207 break; 2208 case 'custom': 2209 dataLayerName = options.GATags.ga_datalayer_name; 2210 break; 2211 default: 2212 dataLayerName = 'dataLayer'; 2213 } 2214 } 2215 this.dataLayerName = dataLayerName; 2216 (function (window, document, src) { 2217 var a = document.createElement('script'), 2218 m = document.getElementsByTagName('script')[0]; 2219 a.async = 1; 2220 a.src = src; 2221 m.parentNode.insertBefore(a, m); 2222 })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName); 2223 2224 window[dataLayerName] = window[dataLayerName] || []; 2225 window.gtag = window.gtag || function gtag() { 2226 window[dataLayerName].push(arguments); 2227 }; 2228 2229 if ( options.google_consent_mode ) { 2230 let data = {}; 2231 data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted'; 2232 data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted'; 2233 data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted'; 2234 data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted'; 2235 2236 this.loadDefaultConsent( 'consent', 'default', data ); 2237 } 2238 2239 gtag('js', new Date()); 2240 gtag_loaded = true; 2241 2242 } 2243 2244 }, 2245 2246 loadDefaultConsent: function() { 2247 window[ this.dataLayerName ].push( arguments ); 2248 }, 2249 2250 loadGTMScript: function (id = '') { 2251 const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com'; 2252 const loader = options.gtm.gtm_container_identifier ?? 'gtm'; 2253 const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed 2254 const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed 2255 const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 2256 2257 window[ datalayer_name ] = window[ datalayer_name ] || []; 2258 window.gtag = window.gtag || function gtag() { 2259 window[ datalayer_name ].push( arguments ); 2260 }; 2261 2262 if ( options.google_consent_mode ) { 2263 let data = {}; 2264 data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted'; 2265 data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted'; 2266 data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted'; 2267 data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted'; 2268 2269 this.GTMdataLayerName = datalayer_name; 2270 this.loadDefaultGTMConsent( 'consent', 'default', data ); 2271 } 2272 2273 (function(w, d, s, l, i) { 2274 w[l] = w[l] || []; 2275 w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); 2276 const f = d.getElementsByTagName(s)[0]; 2277 const j = d.createElement(s); 2278 const dl = l !== 'dataLayer' ? '&l=' + l : ''; 2279 j.async = true; 2280 j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl; 2281 if (gtm_auth && gtm_preview) { 2282 j.src += '>m_auth=' + gtm_auth + '>m_preview=' + gtm_preview + '>m_cookies_win=x'; 2283 } 2284 f.parentNode.insertBefore(j, f); 2285 })(window, document, 'script', datalayer_name, id); 2286 2287 }, 2288 2289 loadDefaultGTMConsent: function() { 2290 window[ this.GTMdataLayerName ].push( arguments ); 2291 }, 2292 2293 /** 2294 * GDPR 2295 */ 2296 2297 loadPixels: function () { 2298 2299 if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) { 2300 2301 // retrieves actual PYS GDPR filters values which allow to avoid cache issues 2302 $.get({ 2303 url: options.ajaxUrl, 2304 dataType: 'json', 2305 data: { 2306 action: 'pys_get_gdpr_filters_values' 2307 }, 2308 success: function (res) { 2309 2310 if (res.success) { 2311 2312 options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api; 2313 options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api; 2314 options.gdpr.tiktok_disabled_by_api = res.data.tiktok_disabled_by_api; 2315 options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api; 2316 options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api; 2317 options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api; 2318 options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api; 2319 options.gdpr.reddit_disabled_by_api = res.data.reddit_disabled_by_api; 2320 2321 options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api; 2322 options.cookie.disabled_all_cookie = res.data.disabled_all_cookie; 2323 options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie; 2324 options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie || !options.enable_lading_page_param; 2325 options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie; 2326 options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie; 2327 options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie; 2328 options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie; 2329 } 2330 loadPixels(); 2331 2332 } 2333 }); 2334 2335 } else { 2336 loadPixels(); 2337 } 2338 2339 }, 2340 2341 consentGiven: function (pixel) { 2342 2343 /** 2344 * Cookiebot 2345 */ 2346 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 2347 2348 var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category']; 2349 2350 if (options.gdpr[pixel + '_prior_consent_enabled']) { 2351 if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) { 2352 return true; 2353 } 2354 } else { 2355 if (Cookiebot.consent[cookiebot_consent_category]) { 2356 return true; 2357 } 2358 } 2359 return false; 2360 2361 } 2362 2363 /** 2364 * Cookie Notice 2365 */ 2366 if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') { 2367 2368 var cn_cookie = Cookies.get(cnArgs.cookieName); 2369 2370 if (options.gdpr[pixel + '_prior_consent_enabled']) { 2371 if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') { 2372 return true; 2373 } 2374 } else { 2375 if (cn_cookie === 'true') { 2376 return true; 2377 } 2378 } 2379 2380 return false; 2381 2382 } 2383 2384 /** 2385 * Cookie Law Info 2386 */ 2387 2388 if (options.gdpr.cookie_law_info_integration_enabled) { 2389 var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy'); 2390 if (options.gdpr[pixel + '_prior_consent_enabled']) { 2391 if (typeof cli_cookie === 'undefined') return true; 2392 if ( 2393 cli_cookie && 2394 (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) 2395 ) { 2396 if (getCookieYes('analytics') === 'yes') { 2397 return true; 2398 } 2399 } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) { 2400 if (Cookies.get('viewed_cookie_policy') === 'yes') { 2401 return true; 2402 } 2403 } 2404 } else { 2405 if ( 2406 cli_cookie && 2407 (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) 2408 ) { 2409 if (getCookieYes('analytics') === 'yes') { 2410 return true; 2411 } 2412 } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) { 2413 if (Cookies.get('viewed_cookie_policy') === 'yes') { 2414 return true; 2415 } 2416 } 2417 } 2418 return false; 2419 } 2420 2421 /** 2422 * ConsentMagic 2423 */ 2424 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 2425 2426 let test_prefix = CS_Data.test_prefix; 2427 if ( 2428 ( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) ) 2429 || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' ) 2430 || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode && pixel == 'reddit' ) 2431 || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' ) 2432 ) { 2433 if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) { 2434 return true; 2435 } else { 2436 return false; 2437 } 2438 } 2439 2440 if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) { 2441 return true; 2442 } else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) { 2443 return true; 2444 } else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) { 2445 return true; 2446 } else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) { 2447 return true; 2448 } else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) { 2449 return true; 2450 } else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) { 2451 return true; 2452 } else if( pixel == 'reddit' && ( CS_Data.cs_script_cat?.reddit == 0 || CS_Data.cs_script_cat?.reddit == CS_Data.cs_necessary_cat_id ) ) { 2453 return true; 2454 } 2455 2456 let substring = "cs_enabled_cookie_term", 2457 theCookies = document.cookie.split( ';' ); 2458 2459 for ( let i = 1; i <= theCookies.length; i++ ) { 2460 if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) { 2461 let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' ); 2462 categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) ); 2463 let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie ); 2464 2465 if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) { 2466 return cs_cookie_val == 'yes'; 2467 } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) { 2468 return cs_cookie_val == 'yes'; 2469 } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) { 2470 return cs_cookie_val == 'yes'; 2471 } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) { 2472 return cs_cookie_val == 'yes'; 2473 } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) { 2474 return cs_cookie_val == 'yes'; 2475 } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) { 2476 return cs_cookie_val == 'yes'; 2477 } else if ( categoryCookie === CS_Data.cs_script_cat?.reddit && pixel == 'reddit' ) { 2478 return cs_cookie_val == 'yes'; 2479 } 2480 } 2481 } 2482 2483 return false; 2484 } 2485 2486 2487 /** 2488 * Real Cookie Banner 2489 */ 2490 if (options.gdpr.real_cookie_banner_integration_enabled) { 2491 var consentApi = window.consentApi; 2492 if (consentApi) { 2493 switch (pixel) { 2494 case "analytics": 2495 return consentApi.consentSync("http", "_ga", "*").cookieOptIn; 2496 case "facebook": 2497 return consentApi.consentSync("http", "_fbp", "*").cookieOptIn; 2498 case "pinterest": 2499
2499 return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn; 2500 case "bing": 2501 return consentApi.consentSync("http", "_uetsid", "*").cookieOptIn; 2502 case "google_ads": 2503 return consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn; 2504 case 'tiktok': 2505 return consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn; 2506 default: 2507 return true; 2508 } 2509 } 2510 } 2511 2512 return true; 2513 2514 }, 2515 2516 setupGdprCallbacks: function () { 2517 2518 let isConcent = false; 2519 2520 /** 2521 * Cookiebot 2522 */ 2523 if ( options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined' ) { 2524 isConcent = true; 2525 window.addEventListener( "CookiebotOnConsentReady", function () { 2526 2527 let consent = { 2528 facebook: true, 2529 ga: true, 2530 google_ads: true, 2531 tiktok: true, 2532 bing: true, 2533 pinterest: true, 2534 gtm: true, 2535 }; 2536 Utils.initializeVideoAPIs( options ); 2537 2538 Utils.manageCookies(); 2539 if ( Cookiebot.consent.marketing ) { 2540 Facebook.loadPixel(); 2541 Bing.loadPixel(); 2542 Pinterest.loadPixel(); 2543 GAds.loadPixel(); 2544 TikTok.loadPixel(); 2545 2546 consent.facebook = true; 2547 consent.bing = true; 2548 consent.google_ads = true; 2549 consent.pinterest = true; 2550 consent.tiktok = true; 2551 } 2552 if ( Cookiebot.consent.statistics ) { 2553 Analytics.loadPixel(); 2554 2555 consent.ga = true; 2556 consent.gtm = true; 2557 } 2558 if ( !Cookiebot.consent.marketing ) { 2559 Facebook.disable(); 2560 Pinterest.disable(); 2561 Bing.disable() 2562 GAds.disable(); 2563 TikTok.disable(); 2564 2565 consent.facebook = false; 2566 consent.bing = false; 2567 consent.google_ads = false; 2568 consent.pinterest = false; 2569 consent.tiktok = false; 2570 } 2571 if ( !Cookiebot.consent.statistics ) { 2572 Analytics.disable(); 2573 2574 consent.ga = false; 2575 consent.gtm = false; 2576 } 2577 2578 Utils.setupGDPRData( consent ); 2579 } ); 2580 } 2581 2582 /** 2583 * Cookie Notice 2584 */ 2585 if ( options.gdpr.cookie_notice_integration_enabled ) { 2586 isConcent = true; 2587 $( document ).onFirst( 'click', '.cn-set-cookie', function () { 2588 2589 let consent = {}; 2590 2591 if ( $( this ).data( 'cookie-set' ) === 'accept' ) { 2592 2593 Utils.initializeVideoAPIs( options ); 2594 2595 Facebook.loadPixel(); 2596 Analytics.loadPixel(); 2597 GAds.loadPixel(); 2598 Pinterest.loadPixel(); 2599 Bing.loadPixel(); 2600 TikTok.loadPixel(); 2601 2602 consent = { 2603 facebook: true, 2604 ga: true, 2605 google_ads: true, 2606 tiktok: true, 2607 bing: true, 2608 pinterest: true, 2609 gtm: true, 2610 }; 2611 } else { 2612 Facebook.disable(); 2613 Analytics.disable(); 2614 GAds.disable(); 2615 Pinterest.disable(); 2616 Bing.disable(); 2617 TikTok.disable(); 2618 2619 consent = {
2620 facebook: false, 2621 ga: false, 2622 google_ads: false, 2623 tiktok: false, 2624 bing: false, 2625 pinterest: false, 2626 gtm: false, 2627 }; 2628 } 2629 Utils.setupGDPRData( consent ); 2630 2631 } ); 2632 2633 $( document ).onFirst( 'click', '.cn-revoke-cookie', function () { 2634 Facebook.disable(); 2635 Analytics.disable(); 2636 GAds.disable(); 2637 Pinterest.disable(); 2638 Bing.disable(); 2639 TikTok.disable(); 2640 2641 let consent = { 2642 facebook: false, 2643 ga: false, 2644 google_ads: false, 2645 tiktok: false, 2646 bing: false, 2647 pinterest: false, 2648 gtm: false, 2649 }; 2650 Utils.setupGDPRData( consent ); 2651 2652 } ); 2653 } 2654 2655 /** 2656 * Cookie Law Info 2657 */ 2658 if ( options.gdpr.cookie_law_info_integration_enabled ) { 2659 isConcent = true; 2660 $( document ).onFirst( 'click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () { 2661 Utils.initializeVideoAPIs( options ); 2662 setTimeout( function () { 2663 let cli_cookie = Cookies.get( 'cookieyes-consent' ) ?? Cookies.get( 'wt_consent' ) ?? Cookies.get( 'viewed_cookie_policy' ); 2664 if ( typeof cli_cookie !== 'undefined' ) { 2665 if ( 2666 cli_cookie && 2667 (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) 2668 ) { 2669 if (getCookieYes('analytics') === 'yes') { 2670 Utils.manageCookies(); 2671 } 2672 } else if ( cli_cookie === Cookies.get( 'viewed_cookie_policy' ) && cli_cookie == 'yes' ) { 2673 Utils.manageCookies(); 2674 } 2675 } 2676 }, 1000 ) 2677 Facebook.loadPixel(); 2678 Analytics.loadPixel(); 2679 GAds.loadPixel(); 2680 Pinterest.loadPixel(); 2681 Bing.loadPixel(); 2682 TikTok.loadPixel(); 2683 2684 let consent = { 2685 facebook: true, 2686 ga: true, 2687 google_ads: true, 2688 tiktok: true, 2689 bing: true, 2690 pinterest: true, 2691 gtm: true, 2692 }; 2693 Utils.setupGDPRData( consent ); 2694 } ); 2695 2696 $( document ).onFirst( 'click', '#cookie_action_close_header_reject, .cky-btn-reject', function () { 2697 Facebook.disable(); 2698 Analytics.disable(); 2699 GAds.disable(); 2700 Pinterest.disable(); 2701 Bing.disable(); 2702 TikTok.disable(); 2703 2704 let consent = { 2705 facebook: false, 2706 ga: false, 2707 google_ads: false, 2708 tiktok: false, 2709 bing: false, 2710 pinterest: false, 2711 gtm: false, 2712 }; 2713 Utils.setupGDPRData( consent ); 2714 } ); 2715 } 2716 2717 /** 2718 * ConsentMagic 2719 */ 2720 if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 2721 isConcent = true; 2722 let test_prefix = CS_Data.test_prefix, 2723 cs_refresh_after_consent = false, 2724 substring = "cs_enabled_cookie_term"; 2725 2726 if ( CS_Data.cs_refresh_after_consent == 1 ) { 2727 cs_refresh_after_consent = CS_Data.cs_refresh_after_consent; 2728 } 2729 2730 let consent_actions = function () { 2731 let theCookies = document.cookie.split( ';' ); 2732 2733 let consent = { 2734 facebook: true, 2735 ga: true, 2736 google_ads: true, 2737 tiktok: true, 2738 bing: true, 2739 pinterest: true, 2740 gtm: true, 2741 reddit: true, 2742 }; 2743 2744 for ( let i = 1; i <= theCookies.length; i++ ) { 2745 if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) { 2746 let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' ); 2747 categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) ); 2748 let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie ); 2749 if ( cs_cookie_val == 'yes' ) { 2750 2751 Utils.initializeVideoAPIs( options ); 2752 2753 if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) { 2754 Facebook.loadPixel(); 2755 } 2756 2757 if ( categoryCookie === CS_Data.cs_script_cat.bing || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) { 2758 Bing.loadPixel(); 2759 } 2760 2761 if ( categoryCookie === CS_Data.cs_script_cat.analytics || ( typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1 ) ) { 2762 Analytics.loadPixel(); 2763 } 2764 if ( categoryCookie === CS_Data.cs_script_cat.gads || ( typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) ) { 2765 GAds.loadPixel(); 2766 } 2767 2768 if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) { 2769 Pinterest.loadPixel(); 2770 } 2771 2772 if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) { 2773 TikTok.loadPixel(); 2774 } 2775 2776 if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode ) ) { 2777 Reddit.loadPixel(); 2778 } 2779 } else { 2780 if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) { 2781 Facebook.disable(); 2782 consent.facebook = false; 2783 } 2784 2785 if ( categoryCookie === CS_Data.cs_script_cat.bing && ( typeof CS_Data.cs_bing_consent_mode == "undefined" || !CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) { 2786 Bing.disable(); 2787 consent.bing = false; 2788 } 2789 2790 if ( categoryCookie === CS_Data.cs_script_cat.analytics && ( typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0 ) ) { 2791 Analytics.disable(); 2792 consent.ga = false; 2793 consent.gtm = false; 2794 } 2795 2796 if ( categoryCookie === CS_Data.cs_script_cat.gads && ( typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0 ) ) { 2797 GAds.disable(); 2798 consent.google_ads = false; 2799 } 2800 2801 if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) { 2802 Pinterest.disable(); 2803 consent.pinterest = false; 2804 } 2805 2806 if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) { 2807 TikTok.disable(); 2808 consent.tiktok = false; 2809 } 2810 2811 if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) && ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || !CS_Data.cs_reddit_ldu_mode ) ) { 2812 Reddit.disable(); 2813 consent.reddit = false; 2814 } 2815 } 2816 if ( Cookies.get( 'cs_enabled_advanced_matching' ) == 'yes' ) { 2817 Facebook.loadPixel(); 2818 } 2819 } 2820 } 2821 2822 Utils.setupGDPRData( consent ); 2823 } 2824 2825 if ( !cs_refresh_after_consent ) { 2826 consent_actions(); 2827 2828 $( document ).on( 'click', '.cs_action_btn', function ( e ) { 2829 e.preventDefault(); 2830 2831 let consent = { 2832 facebook: true, 2833 ga: true, 2834 google_ads: true, 2835 tiktok: true, 2836 bing: true, 2837 pinterest: true, 2838 gtm: true, 2839 reddit: true, 2840 }; 2841 2842 let elm = $( this ), 2843 button_action = elm.attr( 'data-cs_action' ); 2844 2845 if ( button_action === 'allow_all' ) { 2846 2847 Utils.initializeVideoAPIs( options ); 2848 2849 Facebook.loadPixel(); 2850 Bing.loadPixel(); 2851 Analytics.loadPixel(); 2852 GAds.loadPixel(); 2853 Pinterest.loadPixel(); 2854 TikTok.loadPixel(); 2855 Reddit.loadPixel(); 2856 2857 consent.facebook = true; 2858 consent.bing = true; 2859 consent.ga = true; 2860 consent.google_ads = true; 2861 consent.pinterest = true; 2862 consent.tiktok = true; 2863 consent.reddit = true; 2864 consent.gtm = true; 2865 2866 Utils.setupGDPRData( consent ); 2867 2868 } else if ( button_action === 'disable_all' ) { 2869 2870 if (typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) { 2871 Facebook.disable(); 2872 consent.facebook = false; 2873 } 2874 2875 if (typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) { 2876 Bing.disable(); 2877 consent.bing = false; 2878 } 2879 2880 if ( typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0 ) { 2881 Analytics.disable(); 2882 consent.ga = false; 2883 consent.gtm = false; 2884 } 2885 2886 if ( typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0 ) { 2887 GAds.disable(); 2888 consent.google_ads = false; 2889 } 2890 2891 if ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || CS_Data.cs_reddit_ldu_mode == 0 ) { 2892 Reddit.disable(); 2893 consent.reddit = false; 2894 } 2895 2896 Pinterest.disable(); 2897 TikTok.disable(); 2898 2899 consent.pinterest = false; 2900 consent.tiktok = false; 2901 2902 Utils.setupGDPRData( consent ); 2903 } else if ( button_action === 'cs_confirm' ) { 2904 consent_actions(); 2905 } 2906 } ); 2907 } 2908 } 2909 2910 /** 2911 * Real Cookie Banner 2912 */ 2913 if ( options.gdpr.real_cookie_banner_integration_enabled ) { 2914 isConcent = true; 2915 let consentApi = window.consentApi; 2916 if ( consentApi ) { 2917 consentApi.consent( "http", "_ga", "*" ) 2918 .then( Analytics.loadPixel.bind( Analytics ), Analytics.disable.bind( Analytics ) ); 2919 consentApi.consent( "http", "1P_JAR", ".google.com" ) 2920 .then( GAds.loadPixel.bind( GAds ), GAds.disable.bind( GAds ) ); 2921 consentApi.consent( "http", "_fbp", "*" ) 2922 .then( Facebook.loadPixel.bind( Facebook ), Facebook.disable.bind( Facebook ) ); 2923 consentApi.consent( "http", "_pinterest_sess", ".pinterest.com" ) 2924 .then( Pinterest.loadPixel.bind( Pinterest ), Pinterest.disable.bind( Pinterest ) ); 2925 consentApi.consent( "http", "_uetsid", "*" ) 2926 .then( Bing.loadPixel.bind( Bing ), Bing.disable.bind( Bing ) ); 2927 consentApi.consent( "http", "tt_webid_v2", ".tiktok.com" ) 2928 .then( TikTok.loadPixel.bind( TikTok ), TikTok.disable.bind( TikTok ) ); 2929 2930 let consent = { 2931 facebook: true, 2932 ga: true, 2933 google_ads: true, 2934 tiktok: true, 2935 bing: true, 2936 pinterest: true, 2937
2937 gtm: true, 2938 }; 2939 2940 if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) { 2941 consent.ga = false; 2942 consent.gtm = false; 2943 } 2944 if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) { 2945 consent.facebook = false; 2946 } 2947 if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) { 2948 consent.pinterest = false; 2949 } 2950 if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) { 2951 consent.bing = false; 2952 } 2953 if (!consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn) { 2954 consent.google_ads = false; 2955 } 2956 if (!consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn) { 2957 consent.tiktok = false; 2958 } 2959 Utils.setupGDPRData( consent ); 2960 2961 // load WatchVideo event APIs for Auto 2962 /** 2963 * Real Cookie Banner. 2964 */ 2965 if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_youtube ) { 2966 consentApi.consent( "http", "CONSENT", ".youtube.com" ).then( Utils.initYouTubeAPI ); 2967 } 2968 2969 if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_vimeo ) { 2970 consentApi.consent( "http", "player", ".vimeo.com" ).then( Utils.initVimeoAPI ); 2971 } 2972 } 2973 } 2974 2975 if ( !isConcent ) { 2976 Utils.initializeVideoAPIs( options ); 2977 } 2978 }, 2979 2980 setupGDPRData: function ( consent ) { 2981 consent = window.btoa( JSON.stringify( consent ) ); 2982 Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } ); 2983 }, 2984 2985 /** 2986 * Enrich 2987 */ 2988 isCheckoutPage: function () { 2989 return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') || 2990 $('body').hasClass('edd-checkout'); 2991 }, 2992 addCheckoutFields : function() { 2993 var utm = ""; 2994 var utms = getUTMs() 2995 $.each(utmTerms, function (index, name) { 2996 if(index > 0) { 2997 utm+="|"; 2998 } 2999 utm+=name+":"+utms[name]; 3000 }); 3001 var utmIdList = ""; 3002 var utmsIds = getUTMId() 3003 $.each(utmId, function (index, name) { 3004 if(index > 0) { 3005 utmIdList+="|"; 3006 } 3007 utmIdList+=name+":"+utmsIds[name]; 3008 }); 3009 var utmIdListLast = ""; 3010 var utmsIdsLast = getUTMId(true) 3011 $.each(utmId, function (index, name) { 3012 if(index > 0) { 3013 utmIdListLast+="|"; 3014 } 3015 utmIdListLast+=name+":"+utmsIdsLast[name]; 3016 }); 3017 3018 3019 var utmLast = ""; 3020 var utmsLast = getUTMs(true) 3021 $.each(utmTerms, function (index, name) { 3022 if(index > 0) { 3023 utmLast+="|"; 3024 } 3025 utmLast+=name+":"+utmsLast[name]; 3026 }); 3027 3028 var dateTime = getDateTime(); 3029 var landing = Cookies.get('pys_landing_page'); 3030 var lastLanding = Cookies.get('last_pys_landing_page'); 3031 var trafic = Cookies.get('pysTrafficSource'); 3032 var lastTrafic = Cookies.get('last_pysTrafficSource'); 3033 3034 var $form = null; 3035 if($('body').hasClass('woocommerce-checkout')) { 3036 $form = $("form.woocommerce-checkout"); 3037 } else { 3038 $form = $("#edd_purchase_form"); 3039 } 3040 var inputs = {'pys_utm':utm, 3041 'pys_utm_id':utmIdList, 3042 'pys_browser_time':dateTime.join("|"), 3043 'pys_landing':landing, 3044 'pys_source':trafic, 3045 'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal", 3046 3047 'last_pys_landing':lastLanding, 3048 'last_pys_source':lastTrafic, 3049 'last_pys_utm':utmLast, 3050 'last_pys_utm_id':utmIdListLast, 3051 } 3052
3053 Object.keys(inputs).forEach(function(key,index) { 3054 $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> "); 3055 }); 3056 3057 3058 }, 3059 3060 /** 3061 * Advanced From Data 3062 */ 3063 saveAdvancedFormData: function ( email, phone, firstName, lastName, override = true ) { 3064 3065 if ( !options.cookie.disabled_advanced_form_data_cookie ) { 3066 let data = Utils.getAdvancedFormData(); 3067 // Ensure data["address"] is an object 3068 3069 if ( email != null ) { 3070 if ( !override ) { 3071 if ( typeof data[ "email" ] === 'undefined' || !data[ "email" ] ) { 3072 data[ "email" ] = email; 3073 } 3074 } else { 3075 data[ "email" ] = email; 3076 } 3077 3078 if ( typeof data[ "emails" ] === 'object' ) { 3079 if ( override ) { 3080 data[ "emails" ] = [ email, ...Object.values( data[ "emails" ] ) ]; 3081 } else { 3082 data[ "emails" ] = [ ...Object.values( data[ "emails" ] ), email ]; 3083 } 3084 } else { 3085 data[ "emails" ] = [ email ]; 3086 } 3087 data[ "emails" ] = [ ...new Set( data[ "emails" ] ) ]; 3088 data[ "emails" ] = data[ "emails" ].slice( 0, 3 ); 3089 } 3090 3091 if ( phone != null ) { 3092 if ( !override ) { 3093 if ( typeof data[ "phone" ] === 'undefined' || !data[ "phone" ] ) { 3094 data[ "phone" ] = phone; 3095 } 3096 } else { 3097 data[ "phone" ] = phone; 3098 } 3099 3100 if ( typeof data[ "phones" ] === 'object' ) { 3101 if ( override ) { 3102 data[ "phones" ] = [ phone, ...Object.values( data[ "phones" ] ) ]; 3103 } else { 3104 data[ "phones" ] = [ ...Object.values( data[ "phones" ] ), phone ]; 3105 } 3106 } else { 3107 data[ "phones" ] = [ phone ]; 3108 } 3109 data[ "phones" ] = [ ...new Set( data[ "phones" ] ) ]; 3110 data[ "phones" ] = data[ "phones" ].slice( 0, 3 ); 3111 } 3112 3113 if ( firstName != null ) { 3114 if ( !override ) { 3115 if ( typeof data[ "first_name" ] === 'undefined' || !data[ "first_name" ] ) { 3116 data[ "first_name" ] = firstName; 3117 } 3118 } else { 3119 data[ "first_name" ] = firstName; 3120 } 3121 3122 if ( typeof data[ "fns" ] === 'object' ) { 3123 if ( override ) { 3124 data[ "fns" ] = [ firstName, ...Object.values( data[ "fns" ] ) ]; 3125 } else { 3126 data[ "fns" ] = [ ...Object.values( data[ "fns" ] ), firstName ]; 3127 } 3128 } else { 3129 data[ "fns" ] = [ firstName ]; 3130 } 3131 data[ "fns" ] = [ ...new Set( data[ "fns" ] ) ]; 3132 data[ "fns" ] = data[ "fns" ].slice( 0, 2 ); 3133 } 3134 3135 if ( lastName != null ) { 3136 if ( !override ) { 3137 if ( typeof data[ "last_name" ] === 'undefined' || !data[ "last_name" ] ) { 3138 data[ "last_name" ] = lastName; 3139 } 3140 } else { 3141 data[ "last_name" ] = lastName; 3142 } 3143
3144 if ( typeof data[ "lns" ] === 'object' ) { 3145 if ( override ) { 3146 data[ "lns" ] = [ lastName, ...Object.values( data[ "lns" ] ) ]; 3147 } else { 3148 data[ "lns" ] = [ ...Object.values( data[ "fns" ] ), lastName ]; 3149 } 3150 } else { 3151 data[ "lns" ] = [ lastName ]; 3152 } 3153 data[ "lns" ] = [ ...new Set( data[ "lns" ] ) ]; 3154 data[ "lns" ] = data[ "lns" ].slice( 0, 2 ); 3155 } 3156 3157 Cookies.set( 'pys_advanced_form_data', JSON.stringify( data ), { expires: 300,path: '/',domain: domain } ); 3158 } else { 3159 Cookies.remove( 'pys_advanced_form_data', { path: '/',domain: domain } ) 3160 } 3161 if(GTM.isEnabled()){ 3162 GTM.updateEnhancedConversionData(); 3163 } 3164 if(Analytics.isEnabled()){ 3165 Analytics.updateEnhancedConversionData(); 3166 } else if ( GAds.isEnabled() ) { 3167 GAds.updateEnhancedConversionData(); 3168 } 3169 }, 3170 getAdvancedMergeFormData: function (allways_provided_data = false) { 3171 const advanced = Utils.getAdvancedFormData(); 3172 let mergedData = {}, 3173 limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 3 : 1, 3174 address_limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 2 : 1; 3175 3176 if ( options.tracking_analytics.use_encoding_provided_data || allways_provided_data) { 3177 mergedData.sha256_email_address = []; 3178 mergedData.sha256_phone_number = []; 3179 mergedData.address = []; 3180 if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) { 3181 if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) { 3182 Object.keys( options.tracking_analytics.userData.emails ).forEach( ( key ) => { 3183 mergedData.sha256_email_address.push( sha256( options.tracking_analytics.userData.emails[ key ] ) ); 3184 } ) 3185 } 3186 if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) { 3187 Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => { 3188 mergedData.sha256_phone_number.push( sha256( options.tracking_analytics.userData.phones[ key ] ) ); 3189 } ) 3190 } 3191 if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) { 3192 Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => { 3193 let address = Object.assign( {}, options.tracking_analytics.userData.addresses[ key ] ); 3194 3195 if ( address.first_name ) { 3196 address.sha256_first_name = address.first_name !== '' ? sha256( address.first_name ) : ''; 3197 delete address.first_name; 3198 } 3199 if ( address.last_name ) { 3200 address.sha256_last_name = address.last_name !== '' ? sha256( address.last_name ) : ''; 3201 delete address.last_name; 3202 } 3203 mergedData.address.push( address ); 3204 } ) 3205 } 3206 } 3207 3208 let data_persistency = options.data_persistency; 3209 3210 //emails 3211 if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) { 3212 Object.keys( advanced.emails ).forEach( ( ke
3212y ) => { 3213 if ( data_persistency === 'recent_data' ) { 3214 mergedData.sha256_email_address.push( sha256( advanced.emails[ key ] ) ); 3215 } else { 3216 mergedData.sha256_email_address.unshift( sha256( advanced.emails[ key ] ) ); 3217 } 3218 } ) 3219 } 3220 if ( advanced.email && advanced.email !== '' ) { 3221 if ( data_persistency === 'recent_data' ) { 3222 mergedData.sha256_email_address.push( sha256( advanced.email ) ); 3223 } else { 3224 mergedData.sha256_email_address.unshift( sha256( advanced.email ) ); 3225 } 3226 } 3227 mergedData.sha256_email_address = [ ...new Set( mergedData.sha256_email_address ) ]; 3228 mergedData.sha256_email_address = mergedData.sha256_email_address.slice( 0, limit ); 3229 3230 //phones 3231 if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) { 3232 Object.keys( advanced.phones ).forEach( ( key ) => { 3233 if ( data_persistency === 'recent_data' ) { 3234 mergedData.sha256_phone_number.push( sha256( advanced.phones[ key ] ) ); 3235 } else { 3236 mergedData.sha256_phone_number.unshift( sha256( advanced.phones[ key ] ) ); 3237 } 3238 } ) 3239 } 3240 if ( advanced.phone && advanced.phone !== '' ) { 3241 if ( data_persistency === 'recent_data' ) { 3242 mergedData.sha256_phone_number.push( sha256( advanced.phone ) ); 3243 } else { 3244 mergedData.sha256_phone_number.unshift( sha256( advanced.phone ) ); 3245 } 3246 } 3247 mergedData.sha256_phone_number = [ ...new Set( mergedData.sha256_phone_number ) ]; 3248 mergedData.sha256_phone_number = mergedData.sha256_phone_number.slice( 0, limit ); 3249 3250 //first and last names 3251 if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) { 3252 Object.entries( advanced.fns ).forEach( ( item ) => { 3253 if ( mergedData.address.length < address_limit ) { 3254 let first_name = item[ 1 ]; 3255 let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : ''; 3256 let address = { 3257 sha256_first_name: first_name !== '' ? sha256( first_name ) : '', 3258 sha256_last_name: last_name !== '' ? sha256( last_name ) : '', 3259 // Add other address properties here if they exist in advanced 3260 }; 3261 mergedData.address.push( address ); 3262 } 3263 } ) 3264 } 3265 3266 if ( advanced.first_name || advanced.last_name ) { 3267 if ( mergedData.address.length < address_limit ) { 3268 let address = { 3269 sha256_first_name: advanced.first_name !== '' ? sha256( advanced.first_name ) : '', 3270 sha256_last_name: advanced.last_name !== '' ? sha256( advanced.last_name ) : '', 3271 // Add other address properties here if they exist in advanced 3272 }; 3273 mergedData.address.push( address ); 3274 } 3275 } 3276 } else { 3277 mergedData.email = []; 3278 mergedData.phone_number = []; 3279 mergedData.address = []; 3280 if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) { 3281 if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) { 3282 Object.keys( options.tracking_analytics.userData.emails ).forEach( ( ke
3282y ) => { 3283 mergedData.email.push( options.tracking_analytics.userData.emails[ key ] ); 3284 } ) 3285 } 3286 if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) { 3287 Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => { 3288 mergedData.phone_number.push( options.tracking_analytics.userData.phones[ key ] ); 3289 } ) 3290 } 3291 if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) { 3292 Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => { 3293 mergedData.address.push( options.tracking_analytics.userData.addresses[ key ] ); 3294 } ) 3295 } 3296 } 3297 3298 let data_persistency = options.data_persistency; 3299 3300 //emails 3301 if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) { 3302 Object.keys( advanced.emails ).forEach( ( key ) => { 3303 if ( data_persistency === 'recent_data' ) { 3304 mergedData.email.push( advanced.emails[ key ] ); 3305 } else { 3306 mergedData.email.unshift( advanced.emails[ key ] ); 3307 } 3308 } ) 3309 } 3310 if ( advanced.email && advanced.email !== '' ) { 3311 if ( data_persistency === 'recent_data' ) { 3312 mergedData.email.push( advanced.email ); 3313 } else { 3314 mergedData.email.unshift( advanced.email ); 3315 } 3316 } 3317 mergedData.email = [ ...new Set( mergedData.email ) ]; 3318 mergedData.email = mergedData.email.slice( 0, limit ); 3319 3320 //phones 3321 if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) { 3322 Object.keys( advanced.phones ).forEach( ( key ) => { 3323 if ( data_persistency === 'recent_data' ) { 3324 mergedData.phone_number.push( advanced.phones[ key ] ); 3325 } else { 3326 mergedData.phone_number.unshift( advanced.phones[ key ] ); 3327 } 3328 } ) 3329 } 3330 if ( advanced.phone && advanced.phone !== '' ) { 3331 if ( data_persistency === 'recent_data' ) { 3332 mergedData.phone_number.push( advanced.phone ); 3333 } else { 3334 mergedData.phone_number.unshift( advanced.phone ); 3335 } 3336 } 3337 mergedData.phone_number = [ ...new Set( mergedData.phone_number ) ]; 3338 mergedData.phone_number = mergedData.phone_number.slice( 0, limit ); 3339 3340 //first and last names 3341 if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) { 3342 Object.entries( advanced.fns ).forEach( ( item ) => { 3343 if ( mergedData.address.length < address_limit ) { 3344 let first_name = item[ 1 ]; 3345 let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : ''; 3346 let address = { 3347 first_name: first_name || '', 3348 last_name: last_name || '', 3349 // Add other address properties here if they exist in advanced 3350 }; 3351 mergedData.address.push( address ); 3352 } 3353 } ) 3354 } 3355 3356 if ( advanced.first_name || advanced.last_name ) { 3357 if ( mergedData.address.length < address_limit ) { 3358 let address = { 3359 first_name: advanced.first_name || '', 3360 last_name: advanced.last_name || '', 3361 // Add other address properties here if they exist in advanced 3362 }; 3363 mergedData.address.push( address ); 3364 } 3365 } 3366 } 3367 3368 Utils.removeEmptyProperties( mergedData ); 3369 return mergedData; 3370 }, 3371 removeEmptyProperties : function(obj) { 3372 3373 if (obj.hasOwnProperty('address')) { 3374 // ÐÑÐ¾Ñ Ð¾Ð´Ð¸Ð¼ по ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ Ð¼Ð°ÑÑÐ¸Ð²Ñ Ð² 'address' 3375 for (let i = 0; i < obj['address'].length; i++) { 3376 let address1 = obj['address'][i]; 3377 3378 // СÑавниваем Ñ ÐºÐ°Ð¶Ð´Ñм дÑÑгим маÑÑивом в 'address' 3379 for (let j = i + 1; j < obj['address'].length; j++) { 3380 let address2 = obj['address'][j]; 3381 3382 // ÐÑли Ð½Ð°Ñ Ð¾Ð´Ð¸Ð¼ дÑблиÑÑÑÑиеÑÑ ÑвойÑÑва, ÑдалÑем Ð¸Ñ Ð¸Ð· address2 3383 for (let prop in address1) { 3384 if (address1[prop] === address2[prop]) { 3385 delete address2[prop]; 3386 } 3387 } 3388 } 3389 } 3390 } 3391 3392 for (let key in obj) { 3393 if (obj[key] === null || obj[key] === undefined || obj[key] === '') { 3394 delete obj[key]; 3395 } else if (Array.isArray(obj[key])) { 3396 obj[key] = [...new Set(obj[key])]; // Удаление дÑбликаÑов из маÑÑива 3397 obj[key] = obj[key].filter(item => item !== null && item !== undefined && item !== ''); 3398 // ÐбÑабоÑка обÑекÑов внÑÑÑи маÑÑивов 3399 obj[key] = obj[key].map(item => { 3400 if (item === null) { 3401 return; // ÐÑопÑÑкаем null ÑлеменÑÑ 3402 } else if (Array.isArray(item)) { 3403 return this.removeEmptyProperties(item); 3404 } else if (typeof item === 'object') { 3405 let cleanedItem = this.removeEmptyProperties(item); 3406 if (Object.keys(cleanedItem).length > 0) { 3407 return cleanedItem; 3408 } 3409 } else { 3410 return item; 3411 } 3412 }); 3413 // УдалÑем пÑÑÑÑе обÑекÑÑ Ð¸ null из маÑÑива 3414 obj[key] = obj[key].filter(item => item !== undefined && !(typeof item === 'object' && Object.keys(item).length === 0)); 3415 if (obj[key].length === 0) { 3416 delete obj[key]; 3417 } 3418 } else if (typeof obj[key] === 'object') { 3419 this.removeEmptyProperties(obj[key]); 3420 if (Object.keys(obj[key]).length === 0) { 3421 delete obj[key]; 3422 } 3423 } 3424 } 3425 return obj;
3426 }, 3427 getAdvancedFormData: function () { 3428 let dataStr = Cookies.get("pys_advanced_form_data"); 3429 if(dataStr === undefined) { 3430 return {'first_name':"",'last_name':"",'email':"",'phone':"",'fns':[],'lns':[],'emails':[],'phones':[]}; 3431 } else { 3432 return JSON.parse(dataStr); 3433 } 3434 }, 3435 3436 getFormFilledData: function ( event ) { 3437 // First, resolve static/dynamic parameters 3438 if (event.params && Object.keys(event.params).length > 0) { 3439 Object.entries(event.params).forEach(([key, value]) => { 3440 // Resolve parameter value (static or dynamic) 3441 const resolvedValue = resolveParamValue(value, key); 3442 if (resolvedValue !== null) { 3443 event.params[key] = resolvedValue; 3444 } 3445 else { 3446 delete event.params[key]; 3447 } 3448 }); 3449 } 3450 3451 // Then, handle dynamic fields from cookies (existing logic) 3452 3453 if ( Object.keys(options.track_dynamic_fields).length > 0 && Object.keys(event.params).length > 0 ) { 3454 Object.entries(event.params).forEach((item) => { 3455 3456 if ( options.track_dynamic_fields.hasOwnProperty(item[0]) ) { 3457 let fieldData = Cookies.get('pys_dyn_field_' + item[1] ); 3458 3459 if(fieldData !== undefined && fieldData !== '') { 3460 event.params[item[0]] = fieldData; 3461 } else { 3462 delete event.params[item[0]]; 3463 } 3464 } 3465 }) 3466 } 3467 return event; 3468 } 3469 3470 }; 3471 3472 }(options); 3473 3474 var TikTok = function (options) { 3475 3476 var initialized = false; 3477 3478 function fireEvent(name, event) { 3479 3480 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'tiktok')) { 3481 return; 3482 } 3483 3484 var data = event.params; 3485 3486 var ids = event.pixelIds.filter(function (pixelId) { 3487 return !Utils.hideMatchingPixel(pixelId, 'tiktok'); 3488 }) 3489 var params = {}; 3490 Utils.copyProperties(data, params); 3491 3492 params.eventID = Utils.generateUniqueId(event); 3493 3494 if(ids.length > 0){ 3495 TikTok.fireEventAPI(name, event, params); 3496 } 3497 ids.forEach(function(pixelId){ 3498 if (options.debug) { 3499 console.log('[TikTok] ' + name, params,"pixel_id",pixelId); 3500 } 3501 3502 ttq.instance(pixelId).track(name,params) 3503 3504 }); 3505 3506 var customEvent = new CustomEvent('tiktok_event_sent', { 3507 detail: { 3508 eventName: name, 3509 params: params, 3510 pixel_ids: ids 3511 } 3512 }); 3513 window.dispatchEvent(customEvent); 3514 } 3515 3516 return { 3517 tag: function() { 3518 return "tiktok"; 3519 }, 3520 isEnabled: function () { 3521 return options.hasOwnProperty('tiktok'); 3522 }, 3523 getHidePixel: function(){ 3524 if(this.isEnabled() && options.tiktok.hasOwnProperty('hide_pixels')) 3525 { 3526 return options.tiktok.hide_pixels; 3527 } 3528 return []; 3529 }, 3530 disable: function () { 3531 initialized = false; 3532 }, 3533 3534 loadPixel:function () { 3535 if (initialized || !this.isEnabled() || !Utils.consentGiven('tiktok')) { 3536 return; 3537 } 3538 for (var i = 0; i < options.tiktok.pixelIds.length; i++) { 3539 var trackingId = options.tiktok.pixelIds[i]; 3540 if (!Utils.hideMatchingPixel(trackingId, 'tiktok')) { 3541 !function (w, d, t) { 3542 w.TiktokAnalyticsObject=t; 3543 var ttq=w[t]=w[t]||[]; 3544 ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"]; 3545 ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}; 3546 for(var i=0;i<ttq.methods.length;i++) 3547 ttq.setAndDefer(ttq,ttq.methods[i]); 3548 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}; 3549 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)}; 3550 3551 //ttq.load('C60QSCQRVDG9JAKNPK2G'); 3552 //ttq.page(); 3553 }(window, document, 'ttq'); 3554 break; 3555 } 3556 } 3557 3558 3559 var ids = options.tiktok.pixelIds.filter(function (pixelId) { 3560 return !Utils.hideMatchingPixel(pixelId, 'tiktok'); 3561 }) 3562 ids.forEach(function (pixelId) { 3563 3564 ttq.load(pixelId); 3565 ttq.page(); 3566 let advancedMatching = {}; 3567 if(options.tiktok.hasOwnProperty('advanced_matching') 3568 && Object.keys(options.tiktok.advanced_matching).length > 0) { 3569 advancedMatching = options.tiktok.advanced_matching; 3570 if(!advancedMatching.hasOwnProperty("external_id")){ 3571 if (Cookies.get('pbid')) { 3572 advancedMatching["external_id"] = Cookies.get('pbid'); 3573 } 3574 } 3575 else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid')) 3576 { 3577 advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id; 3578 } 3579 3580 ttq.instance(pixelId).identify(advancedMatching) 3581 } 3582 }); 3583 initialized = true; 3584 3585 if (options.staticEvents.hasOwnProperty('tiktok')) { 3586 var timeout = 1; 3587 setTimeout(function (timeout) { 3588 Utils.fireStaticEvents('tiktok', timeout); 3589 }, 1500, timeout) 3590 } 3591 }, 3592 3593 fireEvent: function (name, data) { 3594 if (!initialized || !this.isEnabled()) { 3595 return false; 3596 } 3597 data.delay = data.delay || 0; 3598 3599 if (data.delay === 0) { 3600 fireEvent(name, data); 3601 } else { 3602 setTimeout(function (name, params) { 3603 fireEvent(name, params); 3604 }, data.delay * 1000, name, data); 3605 } 3606 return true; 3607 }, 3608 3609 fireEventAPI: function (name, event, params) { 3610 3611 var ids = event.pixelIds.filter(function (pixelId) { 3612 return !Utils.hideMatchingPixel(pixelId, 'tiktok'); 3613 }) 3614 var notCachedEventsIds = new Array(); 3615 var isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod") 3616 && options.woo.addToCartCatchMethod === "add_cart_js"; 3617 if(!isAddToCartFromJs) { 3618 notCachedEventsIds.push('woo_add_to_cart_on_button_click') 3619 } 3620 3621 if(options.tiktok.serverApiEnabled) { 3622 if(!notCachedEventsIds.includes(event.e_id)) { 3623 3624 var isApiDisabled = options.gdpr.all_disabled_by_api || 3625 options.gdpr.tiktok_disabled_by_api || 3626 options.gdpr.cookiebot_integration_enabled || 3627 options.gdpr.cookie_notice_integration_enabled || 3628 options.gdpr.consent_magic_integration_enabled || 3629 options.gdpr.cookie_law_info_integration_enabled; 3630 // Update eventID 3631 3632 // send event from server if they were block by gdpr or need send with delay 3633 if( options.ajaxForServerEvent || isApiDisabled || event.delay > 0 || event.type !== "static" ){ 3634 3635 var json = { 3636 action: 'pys_tiktok_api_event', 3637 pixel: TikTok.tag(), 3638 event: name, 3639 event_slug: event.e_id, 3640 ids: ids, 3641 data:params, 3642 url:window.location.href, 3643 event_id:params.eventID, 3644 ajax_event:options.ajax_event 3645 }; 3646 3647 let delay = 0; 3648 try { 3649 if (sessionStorage) { 3650 Object.keys(sessionStorage) 3651 .filter(key => key.startsWith('wc_fragments_')) 3652 .forEach((key) => { 3653 let value = sessionStorage.getItem(key); 3654 if (event.e_id === 'woo_add_to_cart_on_button_click') {
3655 delay = 2000; 3656 } 3657 }); 3658 } 3659 } catch (error) { 3660 console.error('sessionStorage is not accessible:', error); 3661 } 3662 3663 3664 if(event.hasOwnProperty('woo_order')) { 3665 json['woo_order'] = event.woo_order; 3666 } 3667 3668 if(event.hasOwnProperty('edd_order')) { 3669 json['edd_order'] = event.edd_order; 3670 } 3671 if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link" || name == 'PageView') { 3672 delay = delay === 0 ? 500 : delay; 3673 setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay); 3674 } else if (event.type != 'static') { 3675 setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay); 3676 } 3677 3678 if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) { 3679 setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay ); 3680 } 3681 } 3682 } 3683 } 3684 }, 3685 3686 onClickEvent: function (event) { 3687 this.fireEvent(event.name, event); 3688 }, 3689 3690 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 3691 3692 window.pysWooProductData = window.pysWooProductData || []; 3693 if (!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3694 return; 3695 3696 if (window.pysWooProductData.hasOwnProperty(product_id)) { 3697 if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) { 3698 3699 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 3700 3701 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()]['params'], event.params); 3702 3703 // maybe customize value option 3704 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 3705 3706 if (product_type === Utils.PRODUCT_BUNDLE) { 3707 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 3708 var items_sum = getBundlePriceOnSingleProduct(data); 3709 event.params.value = (parseFloat(data.base_price) + items_sum) * qty; 3710 } else { 3711 event.params.value = event.params.value * qty; 3712 } 3713 } 3714 3715 event.params.quantity = qty; 3716 3717 this.fireEvent(event.name, event); 3718 3719 } 3720 } 3721 }, 3722 3723 onWooAddToCartOnButtonEvent: function (product_id) { 3724 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3725 return; 3726 3727 if (window.pysWooProductData.hasOwnProperty(product_id)) { 3728 if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) { 3729 var productData = window.pysWooProductData[product_id][this.tag()] 3730 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 3731 3732 Utils.copyProperties(productData['params'], event.params) 3733 event.pixelIds = productData['pixelIds']; 3734 this.fireEvent(event.name, event); 3735 } 3736 } 3737 }, 3738 3739 onEddAddToCartOnButtonEvent : function (download_id, price_index, qty) { 3740 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 3741 return; 3742 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 3743 3744 3745 if (window.pysEddProductData.hasOwnProperty(download_id)) { 3746 3747 var index; 3748 3749 if (price_index) { 3750 index = download_id + '_' + price_index; 3751 } else { 3752 index = download_id; 3753 } 3754 3755 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 3756 if (window.pysEddProductData[download_id][index].hasOwnProperty(this.tag())) { 3757 3758 Utils.copyProperties(window.pysEddProductData[download_id][index][this.tag()].params, event.params); 3759 this.fireEvent(event.name,event); 3760 3761 } 3762 } 3763 3764 } 3765 }, 3766 3767 onPageScroll: function (event) { 3768 if (initialized && this.isEnabled()) { 3769 this.fireEvent(event.name, event); 3770 } 3771 }, 3772 3773 onWatchVideo: function (event) { 3774 if (initialized && this.isEnabled() && !event.fired) { 3775 this.fireEvent(event.name, event); 3776 } 3777 }, 3778 3779 onCommentEvent: function (event) { 3780 if (initialized && this.isEnabled()) { 3781 this.fireEvent(event.name, event); 3782 } 3783 }, 3784 3785 onAdSenseEvent: function (event) { 3786 if (initialized && this.isEnabled()) { 3787 this.fireEvent(event.name, event); 3788 } 3789 }, 3790 3791 onTime: function (event) { 3792 if (initialized && this.isEnabled()) { 3793 this.fireEvent(event.name, event); 3794 } 3795 }, 3796 } 3797 }(options); 3798 3799 var Facebook = function (options) { 3800 3801 var defaultEventTypes = [ 3802 'PageView', 3803 'ViewContent', 3804 'Search', 3805 'AddToCart', 3806 'AddToWishlist',
3807 'InitiateCheckout', 3808 'AddPaymentInfo', 3809 'Purchase', 3810 'Lead', 3811 3812 'Subscribe', 3813 'CustomizeProduct', 3814 'FindLocation', 3815 'StartTrial', 3816 'SubmitApplication', 3817 'Schedule', 3818 'Contact', 3819 'Donate' 3820 ]; 3821 3822 var notCachedEventsIds = new Array(); 3823 var isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod") 3824 && options.woo.addToCartCatchMethod === "add_cart_js"; 3825 if(!isAddToCartFromJs) { 3826 notCachedEventsIds.push('woo_add_to_cart_on_button_click') 3827 } 3828 3829 var initialized = false; 3830 3831 var genereateFbp = function (){ 3832 return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp'); 3833 }; 3834 var genereateFbc = function (){ 3835 return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : '' 3836 }; 3837 3838 var configuredPixels = new Array(); 3839 function fireEvent(name, event) { 3840 3841 3842 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) { 3843 return; 3844 } 3845 3846 var data = event.params; 3847 var ids = event.pixelIds.filter(function (pixelId) { 3848 return !Utils.hideMatchingPixel(pixelId, 'facebook'); 3849 }); 3850 3851 var actionType = defaultEventTypes.includes(name) ? 'trackSingle' : 'trackSingleCustom'; 3852 3853 var params = {}; 3854 3855 Utils.copyProperties(data, params);
3856 Utils.copyProperties(Utils.getRequestParams(), params); 3857 Utils.copyProperties(Utils.getRequestParams(), data); 3858 3859 params = Facebook.filterParams(params); 3860 3861 3862 if(options.facebook.serverApiEnabled) { 3863 if(event.e_id === "woo_remove_from_cart" ) { 3864 Facebook.updateEventId(event.name); 3865 event.eventID = Facebook.getEventId(event.name); 3866 } else if(!notCachedEventsIds.includes(event.e_id)) { 3867 var isApiDisabled = options.gdpr.all_disabled_by_api || 3868 options.gdpr.facebook_disabled_by_api || 3869 options.gdpr.cookiebot_integration_enabled || 3870 options.gdpr.cookie_notice_integration_enabled || 3871 options.gdpr.consent_magic_integration_enabled || 3872 options.gdpr.cookie_law_info_integration_enabled; 3873 // Update eventID 3874 3875 event.eventID = Utils.generateUniqueId(event); 3876 3877 if(Cookies.get('_fbp')){ 3878 params._fbp = Cookies.get('_fbp'); 3879 } 3880 if(Cookies.get('_fbc')){ 3881 params._fbc = Cookies.get('_fbc'); 3882 } 3883 // send event from server if they was bloc by gdpr or need send with delay 3884 if( options.ajaxForServerEvent || isApiDisabled ){ 3885 var json = { 3886 action: 'pys_api_event', 3887 pixel: 'facebook', 3888 event: name, 3889 event_slug: event.e_id, 3890 ids: ids, 3891 data:params, 3892 url:window.location.href, 3893 eventID:event.eventID, 3894 ajax_event:options.ajax_event 3895 }; 3896 3897 if(event.hasOwnProperty('woo_order')) { 3898 json['woo_order'] = event.woo_order; 3899 } 3900 3901 if(event.hasOwnProperty('edd_order')) { 3902 json['edd_order'] = event.edd_order; 3903 } 3904 3905 let delay = 0; 3906 try { 3907 if (sessionStorage) { 3908 Object.keys(sessionStorage) 3909 .filter(key => key.startsWith('wc_fragments_')) 3910 .forEach((key) => { 3911 let value = sessionStorage.getItem(key); 3912 if (event.e_id === 'woo_add_to_cart_on_button_click') { 3913 delay = 2000; 3914 } 3915 }); 3916 } 3917 } catch (error) { 3918 console.error('sessionStorage is not accessible:', error); 3919 } 3920 3921 if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link") { 3922 delay = delay === 0 ? 500 : delay; 3923 setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay); 3924 } else if (event.type != 'static') { 3925 setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay); 3926 } 3927 3928 if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) { 3929 setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay ); 3930 } 3931 } 3932 3933 if( event.e_id !== "automatic_event_signup" && name == "CompleteRegistration" && options.facebook.wooCRSendFromServer ) { 3934 return; 3935 } 3936 } 3937 3938 } 3939 delete params._fbp; 3940 delete params._fbc;
3941 if (options.debug) { 3942 console.log('[Facebook] ' + name, params,"pixel_ids",ids,"eventID",event.eventID); 3943 } 3944 // fire event for each pixel id 3945 ids.forEach(function (pixelId) { 3946 // add eventID for deduplicate events @see https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events/ 3947 var args = {}; 3948 if(options.facebook.serverApiEnabled && event.hasOwnProperty('eventID')) { 3949 args.eventID = event.eventID; 3950 } 3951 Facebook.maybeInitPixel(pixelId); 3952 fbq(actionType,pixelId, name, params,args); 3953 }); 3954 var customEvent = new CustomEvent('facebook_event_sent', { 3955 detail: { 3956 eventName: name, 3957 params: params, 3958 pixel_ids: ids 3959 } 3960 }); 3961 window.dispatchEvent(customEvent); 3962 } 3963 3964 /** 3965 * Public API 3966 */ 3967 return { 3968 tag: function() { 3969 return "facebook"; 3970 }, 3971 isEnabled: function () { 3972 return options.hasOwnProperty('facebook'); 3973 }, 3974 getHidePixel: function(){ 3975 if(this.isEnabled() && options.facebook.hasOwnProperty('hide_pixels')) 3976 { 3977 return options.facebook.hide_pixels; 3978 } 3979 return []; 3980 }, 3981 initEventIdCookies: function (key) { 3982 var ids = {}; 3983 ids[key] = pys_generate_token(36) 3984 Cookies.set('pys_fb_event_id', JSON.stringify(ids), {path: '/',domain: domain}); 3985 }, 3986 3987 updateEventId:function(key) { 3988 var cooData = Cookies.get("pys_fb_event_id") 3989 if(cooData === undefined) { 3990 this.initEventIdCookies(key); 3991 } else { 3992 var data = JSON.parse(cooData); 3993 data[key] = pys_generate_token(36); 3994 Cookies.set('pys_fb_event_id', JSON.stringify(data), {path: '/',domain: domain} ); 3995 } 3996 }, 3997 3998 getEventId:function (key) { 3999 var data = Cookies.get("pys_fb_event_id"); 4000 if(data === undefined) { 4001 this.initEventIdCookies(key); 4002 data = Cookies.get("pys_fb_event_id"); 4003 } 4004 return JSON.parse(data)[key]; 4005 }, 4006 4007 disable: function () { 4008 initialized = false; 4009 }, 4010 4011 filterParams: function (params) { 4012 var filteredParams = {}; 4013 4014 if (options.facebook.hasOwnProperty('enabled_medical') && options.facebook.enabled_medical && options.facebook.hasOwnProperty('do_not_track_medical_param')) { 4015 // Remove empty strings from the array 4016 options.facebook.do_not_track_medical_param = options.facebook.do_not_track_medical_param.filter(Boolean); 4017 for (const key in params) { 4018 if (Array.isArray(options.facebook.do_not_track_medical_param)) { 4019 if (!options.facebook.do_not_track_medical_param.includes(key)) { 4020 filteredParams[key] = params[key]; 4021 } 4022 } 4023 } 4024 } 4025 else { 4026 Utils.copyProperties(params, filteredParams); 4027 } 4028 return filteredParams; 4029 }, 4030 4031 /** 4032 * Load pixel's JS 4033 */ 4034 loadPixel: function () { 4035 if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) { 4036 return; 4037 } 4038 4039 ! function (f, b, e, v, n, t, s) { 4040 if (f.fbq) return; 4041 n = f.fbq = function () { 4042 n.callMethod ? 4043 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 4044 }; 4045 if (!f._fbq) f._fbq = n; 4046 n.push = n; 4047 n.loaded = !0; 4048 n.version = '2.0'; 4049 n.agent = 'dvpixelyoursite'; 4050 n.queue = []; 4051 t = b.createElement(e); 4052 t.async = !0; 4053 t.src = v; 4054 s = b.getElementsByTagName(e)[0]; 4055 s.parentNode.insertBefore(t, s) 4056 }(window, 4057 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 4058 let expires = parseInt(options.cookie_duration); 4059 if(!Cookies.get('_fbp')) { 4060 Cookies.set('_fbp',genereateFbp(), { expires: expires,path: '/',domain: domain }); 4061 } 4062 4063 if(getUrlParameter('fbclid')) { 4064 Cookies.set('_fbc',genereateFbc(), { expires: expires,path: '/',domain: domain }); 4065 } 4066 var ids = options.facebook.pixelIds.filter(function (pixelId) { 4067 return !Utils.hideMatchingPixel(pixelId, 'facebook'); 4068 }); 4069 // initialize default pixel 4070 ids.forEach(function (pixelId) { 4071 Facebook.maybeInitPixel(pixelId); 4072 }); 4073 initialized = true; 4074 4075 Utils.fireStaticEvents('facebook'); 4076 4077 }, 4078 advancedMatching: function () { 4079 if(options.facebook.advancedMatchingEnabled) { 4080 let advancedMatchingForm = Utils.getAdvancedFormData(); 4081 let advancedMatching = {}; 4082 if(Object.keys(options.facebook.advancedMatching).length > 0) { 4083 advancedMatching = options.facebook.advancedMatching; 4084 } 4085 4086 if(!advancedMatching.hasOwnProperty("em") 4087 && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) { 4088 advancedMatching["em"] = advancedMatchingForm["email"]; 4089 } 4090 if(!advancedMatching.hasOwnProperty("ph") 4091 && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) { 4092 advancedMatching["ph"] = advancedMatchingForm["phone"]; 4093 } 4094 if(!advancedMatching.hasOwnProperty("fn") 4095 && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) { 4096 advancedMatching["fn"] = advancedMatchingForm["first_name"]; 4097 } 4098 if(!advancedMatching.hasOwnProperty("ln") 4099 && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) { 4100 advancedMatching["ln"] = advancedMatchingForm["last_name"]; 4101 } 4102 if(!advancedMatching.hasOwnProperty("external_id")){ 4103 if (Cookies.get('pbid')) { 4104 advancedMatching["external_id"] = Cookies.get('pbid'); 4105 } 4106 } 4107 else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid')) 4108 { 4109 advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id; 4110 } 4111 4112 if(Object.keys(advancedMatching).length > 0) { 4113 return advancedMatching; 4114 } 4115 } 4116 return false 4117 }, 4118 maybeInitPixel: function(pixelId) { 4119 4120 if(configuredPixels.includes(pixelId)) return; 4121 4122 if (options.facebook.removeMetadata || Utils.hideMatchingPixel(pixelId, this.tag())) { 4123 fbq('set', 'autoConfig', false, pixelId); 4124 } 4125 let advancedMatching = Facebook.advancedMatching(); 4126 4127 if ( +options.facebook.meta_ldu === 1 ) { 4128 fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 ); 4129 } 4130 4131 if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") { 4132 if(!advancedMatching) { 4133 fbq('init', pixelId); 4134 } else { 4135 var test_prefix = CS_Data.test_prefix; 4136 var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix); 4137 if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) { 4138 if (cs_advanced_matching == 'yes') { 4139 fbq('init', pixelId, advancedMatching); 4140 } else { 4141 fbq('init', pixelId); 4142 } 4143 } else { 4144 fbq('init', pixelId, advancedMatching); 4145 } 4146 } 4147 } else { 4148 if(!advancedMatching) { 4149 fbq('init', pixelId); 4150 } else { 4151 fbq('init', pixelId, advancedMatching); 4152 } 4153 } 4154 configuredPixels.push(pixelId); 4155 }, 4156 4157 fireEvent: function (name, data) { 4158 4159 if (!initialized || !this.isEnabled()) { 4160 return false; 4161 } 4162 4163 data.delay = data.delay || 0; 4164 data.params = data.params || {}; 4165 4166 if (data.delay === 0) { 4167 4168 fireEvent(name, data); 4169 4170 } else { 4171 4172 setTimeout(function (name, params) { 4173 fireEvent(name, params); 4174 }, data.delay * 1000, name, data); 4175 4176 } 4177 4178 return true; 4179 4180 }, 4181 4182 onAdSenseEvent: function (event) { 4183 this.fireEvent(event.name, event); 4184 }, 4185 4186 onClickEvent: function (event) { 4187 this.fireEvent(event.name, event); 4188 }, 4189 4190 onWatchVideo: function (event) { 4191 this.fireEvent(event.name, event); 4192 }, 4193 4194 onCommentEvent: function (event) { 4195 this.fireEvent(event.name, event); 4196 }, 4197 4198 onFormEvent: function (event) { 4199 this.fireEvent(event.name, event); 4200 }, 4201 4202 onDownloadEvent: function (event) { 4203 this.fireEvent(event.name, event); 4204 4205 }, 4206 4207 4208 onWooAddToCartOnButtonEvent: function (product_id) { 4209 4210 window.pysWooProductData = window.pysWooProductData || []; 4211 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4212 return; 4213 4214 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4215 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 4216 4217 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 4218 4219 Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params) 4220 event.pixelIds = window.pysWooProductData[product_id]['facebook']['pixelIds']; 4221 this.fireEvent(event.name, event); 4222 } 4223 } 4224 }, 4225 4226 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 4227 4228 window.pysWooProductData = window.pysWooProductData || []; 4229 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4230 return; 4231 4232 if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) { 4233 product_id = parseInt($form.find('input[name="variation_id"]').val()); 4234 } 4235 4236 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4237 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 4238 4239 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click.facebook); 4240 4241 4242 Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params); 4243 4244 var groupValue = 0; 4245 if(product_type === Utils.PRODUCT_GROUPED ) { 4246 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 4247 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 4248 var quantity = parseInt($(this).val()); 4249 if(isNaN(quantity)) { 4250 quantity = 0; 4251 } 4252 var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId]; 4253 4254 if(quantity == 0) { 4255 event.params.content_ids.forEach(function(el,index,array) { 4256 if(el == childItem.content_id) { 4257 array.splice(index, 1); 4258 } 4259 }); 4260 } 4261 4262 if(event.params.hasOwnProperty('contents')) { 4263 event.params.contents.forEac
4263h(function(el,index,array) { 4264 if(el.id == childItem.content_id) { 4265 if(quantity > 0){ 4266 el.quantity = quantity; 4267 } else { 4268 array.splice(index, 1); 4269 } 4270 } 4271 }); 4272 } 4273 4274 4275 groupValue += childItem.price * quantity; 4276 }); 4277 if(groupValue == 0) return; // skip if no items selected 4278 } 4279 4280 4281 4282 // maybe customize value option 4283 if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') { 4284 4285 if(product_type === Utils.PRODUCT_GROUPED) { 4286 event.params.value = groupValue; 4287 } else if(product_type === Utils.PRODUCT_BUNDLE) { 4288 var data = $(".bundle_form .bundle_data").data("bundle_form_data"); 4289 var items_sum = getBundlePriceOnSingleProduct(data); 4290 event.params.value = (parseFloat(data.base_price) + items_sum )* qty; 4291 } else { 4292 event.params.value = event.params.value * qty; 4293 } 4294 } 4295 4296 // only when non Facebook for WooCommerce logic used 4297 if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) { 4298 event.params.contents[0].quantity = qty; 4299 4300 } 4301 4302 var event_name = is_external ? options.woo.affiliateEventName : event.name; 4303 4304 this.fireEvent(event_name, event); 4305 4306 } 4307 } 4308 4309 }, 4310 4311 onWooRemoveFromCartEvent: function (event) { 4312 this.fireEvent(event.name, event); 4313 }, 4314 4315 onWooAffiliateEvent: function (product_id) { 4316 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 4317 return; 4318 var event = Utils.clone(options.dynamicEvents.woo_affiliate[this.tag()]); 4319 4320 4321 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4322 if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) { 4323 4324 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()].params, event.params) 4325 this.fireEvent(options.woo.affiliateEventName, event); 4326 4327 } 4328 } 4329 4330 }, 4331 4332 onWooPayPalEvent: function (event) { 4333 this.fireEvent(event.name, event); 4334 }, 4335 4336 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 4337 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4338 return; 4339 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 4340 4341 if (window.pysEddProductData.hasOwnProperty(download_id)) { 4342 4343 var index; 4344 4345 if (price_index) { 4346 index = download_id + '_' + price_index; 4347 } else { 4348 index = download_id; 4349 } 4350 4351 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 4352 if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) { 4353 4354 Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params) 4355 4356 // maybe customize value option 4357 if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') { 4358 event.params.value = event.params.value * qty; 4359 } 4360 4361 // update contents qty param 4362 var contents = event.params.contents; 4363 contents[0].quantity = qty; 4364 event.params.contents = contents; 4365 4366 this.fireEvent(event.name,event); 4367 4368 } 4369 } 4370 4371 } 4372 4373 }, 4374 4375 onEddRemoveFromCartEvent: function (event) { 4376 this.fireEvent(event.name, event); 4377 }, 4378 onPageScroll: function (event) { 4379 this.fireEvent(event.name, event); 4380 }, 4381 onTime: function (event) { 4382 this.fireEvent(event.name, event); 4383 }, 4384 }; 4385 4386 }(options); 4387 4388 var Analytics = function (options) { 4389 4390 var initialized = false; 4391 var isAllowEnhancedConversions = false; 4392 4393 /** 4394 * Fires event 4395 * 4396 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 4397 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 4398 * @link: https://developers.google.com/gtagjs/reference/event 4399 * @link: https://developers.google.com/gtagjs/reference/parameter 4400 * 4401 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
4401s-mets 4402 * 4403 * @param name 4404 * @param data 4405 */ 4406 function fireEvent(name, event) { 4407 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) { 4408 return; 4409 } 4410 4411 var eventParams = event.params; 4412 var valuesArray = Object.values(event.trackingIds); 4413 var ids = valuesArray.filter(function (pixelId) { 4414 return loadTags.some(loadTag => pixelId.startsWith(loadTag)) && !Utils.hideMatchingPixel(pixelId, 'ga') && !Utils.hideMatchingPixel(pixelId, 'google_ads'); 4415 }) 4416 4417 // Generate unique event_id for deduplication 4418 eventParams.event_id = Utils.generateUniqueId(event); 4419 event.eventID = Utils.generateUniqueId(event); 4420 4421 Utils.copyProperties(Utils.getRequestParams(), eventParams); 4422 4423 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify
4423it 4424 var params = mapParamsTov4(ids,name,copyParams) 4425 4426 var _fireEvent = function (tracking_ids,name,params) { 4427 4428 params['send_to'] = tracking_ids; 4429 4430 if (options.debug) { 4431 console.log('[Google Analytics #' + tracking_ids + '] ' + name, params); 4432 } 4433 4434 // Send via gtag 4435 gtag('event', name, params); 4436 4437 var customEvent = new CustomEvent('gtag_event_sent', { 4438 detail: { 4439 eventName: name, 4440 params: params, 4441 pixel_ids: tracking_ids 4442 } 4443 }); 4444 window.dispatchEvent(customEvent); 4445 }; 4446 4447 4448 delete params.analytics_storage; 4449 delete params.ad_storage; 4450 delete params.ad_user_data; 4451 delete params.ad_personalization; 4452 4453 if(options.hasOwnProperty('google_ads')){ 4454 var conversion_event_name = event.e_id; 4455 switch ( conversion_event_name ) { 4456 case "woo_add_to_cart_on_cart_page": 4457 case "woo_add_to_cart_on_checkout_page": 4458 case "woo_add_to_cart_on_button_click": 4459 conversion_event_name = 'woo_add_to_cart'; 4460 break; 4461 case "edd_add_to_cart_on_cart_page": 4462 case "edd_add_to_cart_on_checkout_page": 4463 case "edd_add_to_cart_on_button_click": 4464 conversion_event_name = 'edd_add_to_cart'; 4465 break; 4466 case "automatic_event_adsense": 4467 case "automatic_event_comment": 4468 case "automatic_event_download": 4469 case "automatic_event_email_link": 4470 case "automatic_event_form": 4471 case "automatic_event_internal_link": 4472 case "automatic_event_outbound_link": 4473 case "automatic_event_scroll": 4474 case "automatic_event_tel_link": 4475 case "automatic_event_time_on_page": 4476 case "automatic_event_video": 4477 conversion_event_name = 'automatic_event'; 4478 break; 4479 } 4480 4481 if ( conversion_event_name !== 'automatic_event' && 4482 typeof options.google_ads[conversion_event_name + '_conversion_track'] !== 'undefined' ) { 4483 const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ]; 4484 4485 if ( conversionTrack === 'conversion' ) { 4486 ids = ids.map(id => id.split('/')[0]) 4487 } 4488 } 4489 } 4490 4491 4492 _fireEvent(ids, name, params); 4493 if(event.hasOwnProperty('unify') && event.unify){ 4494 isTrackEventForGA.push(name); 4495 } 4496 } 4497 4498 function normalizeEventName(eventName) { 4499 4500 var matches = { 4501 ViewContent: 'view_item', 4502 AddToCart: 'add_to_cart', 4503 AddToWishList: 'add_to_wishlist', 4504 InitiateCheckout: 'begin_checkout', 4505 Purchase: 'purchase', 4506 Lead: 'generate_lead', 4507 CompleteRegistration: 'sign_up', 4508 AddPaymentInfo: 'set_checkout_option' 4509 }; 4510 4511 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 4512 4513 } 4514 4515 function mapParamsTov4(tag,name,param) { 4516 //GA4 automatically collects a number of parameters for all events 4517 var hasGA4Tag = false; 4518 4519 // end 4520 if (Array.isArray(tag)) { 4521 hasGA4Tag = tag.some(function (element) { 4522 return isv4(element); 4523 }); 4524 } else if(isv4(tag)) { 4525 // tag ÑвлÑеÑÑÑ ÑÑÑокой и ÑооÑвеÑÑÑвÑÐµÑ GA4 4526 hasGA4Tag = true; 4527 } 4528 if(hasGA4Tag) { 4529 delete param.event_category; 4530 delete param.event_label; 4531 delete param.ecomm_prodid; 4532 delete param.ecomm_pagetype; 4533 delete param.ecomm_totalvalue; 4534 if(name === 'search') { 4535 param['search'] = param.search_term; 4536 delete param.search_term; 4537 delete param.dynx_itemid; 4538 delete param.dynx_pagetype; 4539 delete param.dynx_totalvalue; 4540 } 4541 } 4542 return param; 4543 } 4544 4545 function isv4(tag) { 4546 return tag.indexOf('G') === 0; 4547 } 4548 4549 /** 4550 * Public API 4551 */ 4552 return { 4553 tag: function() { 4554 return "ga"; 4555 }, 4556 isEnabled: function () { 4557 return options.hasOwnProperty('ga'); 4558 }, 4559 getHidePixel: function(){ 4560 if(this.isEnabled() && options.ga.hasOwnProperty('hide_pixels')) 4561 { 4562 return options.ga.hide_pixels; 4563 } 4564 return []; 4565 }, 4566 disable: function () { 4567 initialized = false; 4568 }, 4569 updateEnhancedConversionData : function () { 4570 if (!initialized || !this.isEnabled()) { 4571 return; 4572 } 4573 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) { 4574 var advanced = Utils.getAdvancedMergeFormData(); 4575 if (Object.keys(advanced).length > 0) { 4576 gtag('set', 'user_data', advanced); 4577 } 4578 } 4579 }, 4580 loadPixel: function () { 4581 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 4582 return; 4583 } 4584 4585 4586 for (var i = 0; i < options.ga.trackingIds.length; i++) { 4587 var trackingId = options.ga.trackingIds[i]; 4588 if (!Utils.hideMatchingPixel(trackingId, 'ga')) { 4589 Utils.loadGoogleTag(trackingId); 4590 break; 4591 } 4592 } 4593 4594 4595 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){ 4596 var advanced = Utils.getAdvancedMergeFormData(); 4597 if(Object.keys(advanced).length > 0){ 4598 gtag('set', 'user_data', advanced); 4599 } 4600 } 4601 4602 var config = {}; 4603 4604 if(options.user_id && options.user_id != 0) { 4605 config.user_id = options.user_id; 4606 } 4607 config.url_passthrough = options.ga.url_passthrough; 4608 // Cross-Domain tracking 4609 if (options.ga.crossDomainEnabled) { 4610 config.linker = { 4611 accept_incoming: options.ga.crossDomainAcceptIncoming, 4612 domains: options.ga.crossDomainDomains 4613 }; 4614 } 4615 4616 var ids = options.ga.trackingIds.filter(function (pixelId) { 4617 return !Utils.hideMatchingPixel(pixelId, 'ga'); 4618 }); 4619 loadTags.push(...ids); 4620 ids.forEach(function (trackingId,index) { 4621 4622 var obj = options.ga.isDebugEnabled; 4623 var searchValue = "index_"+index; 4624 var config_for_tag = Object.assign({}, config); 4625 config_for_tag.debug_mode = false; 4626 config_for_tag.send_page_view = !options.ga.custom_page_view_event; 4627 for (var key in obj) { 4628 if (obj[key] === searchValue) { 4629 config_for_tag.debug_mode = true; 4630 break; 4631 } 4632 } 4633 if(!config_for_tag.debug_mode) 4634 { 4635 delete config_for_tag.debug_mode; 4636 } 4637 4638 if(isv4(trackingId)) { 4639 if(options.ga.disableAdvertisingPersonalization) { 4640 config_for_tag.allow_ad_personalization_signals = false 4641 } 4642 } 4643 if(options.ga.hasOwnProperty('additionalConfig')){ 4644 if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){ 4645 config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection; 4646 } 4647 4648 } 4649 if(options.ga.hasOwnProperty('serverContainerUrls')){ 4650 if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){ 4651 if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){ 4652 config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url; 4653 } 4654 if(options.ga.serverContainerUrls[trackingId].transport_url != ''){ 4655 config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url; 4656 } 4657 } 4658 } 4659 if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') { 4660 var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category']; 4661 if (options.gdpr['analytics_prior_consent_enabled']) { 4662 if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) { 4663 gtag('config', trackingId, config_for_tag); 4664 } 4665 } else { 4666 if (Cookiebot.consent[cookiebot_consent_category]) { 4667 gtag('config', trackingId, config_for_tag); 4668 } 4669 } 4670 } 4671 else 4672 { 4673 gtag('config', trackingId, config_for_tag); 4674 } 4675 }); 4676 if(!isAdsLoad && GAds.isEnabled() && options.google_ads.conversion_ids.length > 0 && Utils.consentGiven('google_ads')) { 4677 for (var i = 0; i < options.google_ads.conversion_ids.length; i++) { 4678 var trackingId = options.google_ads.conversion_ids[i]; 4679 if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) { 4680 Utils.loadGoogleTag(trackingId); 4681 break; 4682 } 4683 } 4684 var ids = options.google_ads.conversion_ids.filter(function (pixelId) { 4685 return !Utils.hideMatchingPixel(pixelId, 'google_ads'); 4686 }); 4687 loadTags.push(...ids); 4688 // configure conversion ids 4689 ids.forEach(function (conversion_id,index) { 4690 4691 gtag('config', conversion_id); 4692 4693 if(options.google_ads.enhanced_conversion.includes("index_"+index)) { 4694 isAllowEnhancedConversions = true 4695 gtag('config', conversion_id,{ 'allow_enhanced_conversions':true });
4696 } 4697 4698 }); 4699 isAdsLoad = true; 4700 } 4701 4702 initialized = true; 4703 4704 Utils.fireStaticEvents('ga'); 4705 $( document).trigger( "analytics_initialized") 4706 }, 4707 4708 fireEvent: function (name, data) { 4709 4710 if (!initialized || !this.isEnabled()) { 4711 return false; 4712 } 4713 4714 data.delay = data.delay || 0; 4715 data.params = data.params || {}; 4716 4717 if (data.delay === 0) { 4718 4719 fireEvent(name, data); 4720 4721 } else { 4722 4723 setTimeout(function (name, params) { 4724 fireEvent(name, params); 4725 }, data.delay * 1000, name, data); 4726 4727 } 4728 4729 return true; 4730 4731 }, 4732 4733 onAdSenseEvent: function (event) { 4734 this.fireEvent(event.name, event); 4735 }, 4736 4737 onClickEvent: function (event) { 4738 this.fireEvent(event.name, event); 4739 }, 4740 4741 onWatchVideo: function (event) { 4742 if(!event.hasOwnProperty("youtube_disabled") 4743 || !event.youtube_disabled 4744 || event.params.video_type !== "youtube") { 4745 this.fireEvent(event.name, event); 4746 } 4747 }, 4748 4749 onCommentEvent: function (event) { 4750 4751 this.fireEvent(event.name, event); 4752 4753 }, 4754 4755 onFormEvent: function (event) { 4756 4757 this.fireEvent(event.name, event); 4758 4759 }, 4760 4761 onDownloadEvent: function (event) { 4762 4763 this.fireEvent(event.name, event); 4764 4765 }, 4766 4767 onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) { 4768 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4769 return; 4770 4771 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4772 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 4773 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 4774 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params) 4775 event.trackingIds = window.pysWooProductData[product_id]['ga']['trackingIds']; 4776 if(prod_info) 4777 { 4778 if(prod_info['pys_list_name_productlist_id']) 4779 { 4780 event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id'] 4781 } 4782 if(prod_info['pys_list_name_productlist_name']) 4783 { 4784 event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name'] 4785 } 4786 } 4787 this.fireEvent(event.name, event); 4788 } 4789 } 4790 4791 }, 4792 4793 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) { 4794 4795 window.pysWooProductData = window.pysWooProductData || []; 4796 4797 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4798 return; 4799 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 4800 4801 if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) { 4802 product_id = parseInt($form.find('input[name="variation_id"]').val()); 4803 } 4804 4805 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4806 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 4807 4808 Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params); 4809 4810 4811 if(product_type === Utils.PRODUCT_GROUPED ) { 4812 var groupValue = 0; 4813 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 4814 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 4815 var quantity = parseInt($(this).val()); 4816 if(isNaN(quantity)) { 4817 quantity = 0; 4818 } 4819 var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
4820 event.params.items.forEach(function(el,index,array) { 4821 if(el.id == childItem.content_id) { 4822 if(quantity > 0){ 4823 el.quantity = quantity; 4824 el.price = childItem.price; 4825 } else { 4826 array.splice(index, 1); 4827 } 4828 } 4829 }); 4830 groupValue += childItem.price * quantity; 4831 }); 4832 4833 if(options.woo.addToCartOnButtonValueEnabled && 4834 options.woo.addToCartOnButtonValueOption !== 'global' && 4835 event.params.hasOwnProperty('value')) { 4836 event.params.value = groupValue; 4837 } 4838 4839 if(groupValue == 0) return; // skip if no items selected 4840 } else { 4841 // update items qty param 4842 event.params.items[0].quantity = qty; 4843 } 4844 4845 // maybe customize value option 4846 if (options.woo.addToCartOnButtonValueEnabled && 4847 options.woo.addToCartOnButtonValueOption !== 'global' && 4848 product_type !== Utils.PRODUCT_GROUPED) 4849 { 4850 if(event.params.hasOwnProperty('value')) { 4851 event.params.value = event.params.items[0].price * qty; 4852 } 4853 } 4854 4855 if(prod_info) 4856 { 4857 if(prod_info['pys_list_name_productlist_id']) 4858 { 4859 event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id'] 4860 } 4861 if(prod_info['pys_list_name_productlist_name']) 4862 { 4863 event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name'] 4864 } 4865 } 4866 4867 var eventName = is_external ? options.woo.affiliateEventName : event.name; 4868 eventName = normalizeEventName(eventName); 4869 4870 this.fireEvent(eventName, event); 4871 4872 } 4873 } 4874 4875 }, 4876 4877 onWooCheckoutProgressStep: function (event) { 4878 this.fireEvent(event.name, event); 4879 }, 4880 4881 onWooSelectContent: function (event) { 4882 const select_prod_list = {}; 4883 4884 if (event.params.items[0].item_list_name !== undefined) { 4885 select_prod_list.list_name = event.params.items[0].item_list_name; 4886 } 4887 4888 if (event.params.items[0].item_list_id !== undefined) { 4889 select_prod_list.list_id = event.params.items[0].item_list_id; 4890 } 4891 const url = new URL(window.location.href); 4892 select_prod_list.url = url.origin + url.pathname; 4893 Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' }); 4894 this.fireEvent(event.name, event); 4895 }, 4896 4897 onWooRemoveFromCartEvent: function (event) { 4898 this.fireEvent(event.name, event); 4899 }, 4900 4901 onWooAffiliateEvent: function (product_id) { 4902 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 4903 return; 4904 var event = options.dynamicEvents.woo_affiliate[this.tag()]; 4905 4906 if (window.pysWooProductData.hasOwnProperty(product_id)) { 4907 if (window.pysWooProductData[product_id].hasOwnProperty('ga')) { 4908 4909 event = Utils.clone(event ); 4910 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params) 4911 this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event); 4912 4913 } 4914 } 4915 4916 }, 4917 4918 onWooPayPalEvent: function (event) { 4919 this.fireEvent(event.name, event); 4920 }, 4921 4922 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 4923 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 4924 return; 4925 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 4926 4927 4928 if (window.pysEddProductData.hasOwnProperty(download_id)) { 4929 4930 var index; 4931 4932 if (price_index) { 4933 index = download_id + '_' + price_index; 4934 } else { 4935 index = download_id; 4936 } 4937 4938 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 4939 if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) { 4940 4941 Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params); 4942 4943 // update items qty param 4944 event.params.items[0].quantity = qty; 4945 4946 this.fireEvent(event.name,event); 4947 4948 } 4949 } 4950 4951 } 4952 4953 }, 4954 4955 onEddRemoveFromCartEvent: function (event) { 4956 this.fireEvent(event.name, event); 4957 }, 4958 4959 onPageScroll: function (event) { 4960 if (initialized && this.isEnabled()) { 4961 this.fireEvent(event.name, event); 4962 } 4963 }, 4964 onTime: function (event) { 4965 if (initialized && this.isEnabled()) { 4966 this.fireEvent(event.name, event); 4967 } 4968 }, 4969 }; 4970 4971 }(options); 4972 4973 var GAds = function (options) { 4974 4975 var initialized = false; 4976 var isAllowEnhancedConversions = false 4977 /** 4978 * Fires event 4979 * 4980 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data 4981 * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events 4982 * @link: https://developers.google.com/gtagjs/reference/event 4983 * @link: https://developers.google.com/gtagjs/reference/parameter 4984 */ 4985 function fireEvent(name, data) { 4986 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(event_name,'google_ads')) { 4987 return; 4988 } 4989 var _params = Utils.copyProperties(data.params,{}); 4990 4991 _params.event_id = Utils.generateUniqueId(data); 4992 4993 var ids = data.ids.filter(function (pixelId) { 4994 return !Utils.hideMatchingPixel(pixelId, 'google_ads'); 4995 }); 4996 4997 var conversionIds = data.hasOwnProperty('conversion_ids') ? data.conversion_ids.filter(function (conversion_id) { 4998 return !Utils.hideMatchingPixel(conversion_id, 'google_ads'); 4999 }) : []; 5000 var conversion_labels = data.hasOwnProperty('conversion_labels') ? data.conversion_labels.filter(function (conversion_label) { 5001 conversion_id = conversion_label.split('/')[0]; 5002 return !Utils.hideMatchingPixel(conversion_id, 'google_ads'); 5003 }) : []; 5004
5005 Utils.copyProperties(Utils.getRequestParams(), _params); 5006 var _fireEvent = function (conversion_id,event_name) { 5007 5008 params = Utils.copyProperties(_params, { send_to: conversion_id }); 5009 5010 if("conversion" === event_name) { 5011 delete params.items; 5012 delete params.ecomm_pagetype; 5013 delete params.ecomm_prodid; 5014 delete params.ecomm_totalvalue; 5015 } 5016 5017 if (options.debug) { 5018 console.log('[Google Ads #' + conversion_id + '] ' + event_name, params); 5019 } 5020 gtag('event', event_name, params); 5021 var customEvent = new CustomEvent('gtag_event_sent', { 5022 detail: { 5023 eventName: event_name, 5024 params: params, 5025 pixel_ids: conversion_id 5026 } 5027 }); 5028 window.dispatchEvent(customEvent); 5029 5030 }; 5031 5032 5033 if ( conversion_labels.length > 0 ) { 5034 ids = conversion_labels; 5035 if ( !isTrackEventForGA.includes( name ) ) { 5036 _fireEvent( ids, name ); 5037 } 5038 } else { 5039 var conversion_event_name = data.e_id; 5040 switch ( conversion_event_name ) { 5041 case "woo_add_to_cart_on_cart_page": 5042 case "woo_add_to_cart_on_checkout_page": 5043 case "woo_add_to_cart_on_button_click": 5044 conversion_event_name = 'woo_add_to_cart'; 5045 break; 5046 case "edd_add_to_cart_on_cart_page": 5047 case "edd_add_to_cart_on_checkout_page": 5048 case "edd_add_to_cart_on_button_click": 5049 conversion_event_name = 'edd_add_to_cart'; 5050 break; 5051 case "automatic_event_adsense": 5052 case "automatic_event_comment": 5053 case "automatic_event_download": 5054 case "automatic_event_email_link": 5055 case "automatic_event_form": 5056 case "automatic_event_internal_link": 5057 case "automatic_event_outbound_link": 5058 case "automatic_event_scroll": 5059 case "automatic_event_tel_link": 5060 case "automatic_event_time_on_page": 5061 case "automatic_event_video": 5062 conversion_event_name = 'automatic_event'; 5063 break; 5064 } 5065 5066 if ( ids.length ) { 5067 if ( conversion_event_name !== 'automatic_event' && options.hasOwnProperty('google_ads') && options.google_ads[ conversion_event_name + '_conversion_track' ] ) { 5068 const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ]; 5069 5070 if ( conversionTrack === 'conversion' ) { 5071 _fireEvent( ids, "conversion" ); 5072 ids = conversionIds; 5073 } 5074 } 5075 } else { 5076 ids = conversionIds; 5077 } 5078 5079 if ( !isTrackEventForGA.includes( name ) ) { 5080 _fireEvent( ids, name ); 5081 } 5082 } 5083 } 5084 5085 function normalizeEventName(eventName) { 5086 5087 var matches = { 5088 ViewContent: 'view_item', 5089 AddToCart: 'add_to_cart', 5090 AddToWishList: 'add_to_wishlist', 5091 InitiateCheckout: 'begin_checkout', 5092 Purchase: 'purchase', 5093 Lead: 'generate_lead', 5094 CompleteRegistration: 'sign_up', 5095 AddPaymentInfo: 'set_checkout_option' 5096 }; 5097 5098 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 5099 5100 } 5101 5102 /** 5103 * Public API 5104 */ 5105 return { 5106 tag: function() { 5107 return "google_ads"; 5108 }, 5109 isEnabled: function () { 5110 return options.hasOwnProperty('google_ads'); 5111 }, 5112 getHidePixel: function(){ 5113 if(this.isEnabled() && options.google_ads.hasOwnProperty('hide_pixels')) 5114 { 5115 return options.google_ads.hide_pixels; 5116 } 5117 return []; 5118 }, 5119 disable: function () { 5120 initialized = false; 5121 }, 5122 5123 updateEnhancedConversionData : function () { 5124 5125 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){ 5126 var advanced = Utils.getAdvancedMergeFormData() 5127 gtag('set', 'user_data', advanced); 5128 } 5129 }, 5130 5131 loadPixel: function () { 5132 5133 if (initialized || !this.isEnabled() || !Utils.consentGiven('google_ads')) { 5134 return; 5135 } 5136 var ids = options.google_ads.conversion_ids.filter(function (pixelId) { 5137 return !Utils.hideMatchingPixel(pixelId, 'google_ads'); 5138 }); 5139 loadTags.push(...ids); 5140 if(!isAdsLoad && options.google_ads.conversion_ids.length > 0){ 5141 for (var i = 0; i < options.google_ads.conversion_ids.length; i++) { 5142 var trackingId = options.google_ads.conversion_ids[i]; 5143 if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) { 5144 Utils.loadGoogleTag(trackingId); 5145 break; 5146 } 5147 } 5148 5149 // configure conversion ids 5150 ids.forEach(function (conversion_id,index) { 5151 5152 let config = {}; 5153 5154 if(options.google_ads.enhanced_conversion.includes("index_"+index)) { 5155 isAllowEnhancedConversions = true; 5156 config.allow_enhanced_conversions = true 5157 } 5158 5159 // Cross-Domain tracking 5160 if (options.google_ads.crossDomainEnabled) { 5161 config.linker = { 5162 accept_incoming: options.google_ads.crossDomainAcceptIncoming, 5163 domains: options.google_ads.crossDomainDomains 5164 }; 5165 } 5166 5167 gtag('config', conversion_id, config ); 5168 5169 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnableuserDataEnable){ 5170 var advanced = Utils.getAdvancedMergeFormData() 5171 gtag('set', 'user_data', advanced); 5172 } 5173 5174 }); 5175 isAdsLoad = true; 5176 } 5177 5178 initialized = true; 5179 5180 Utils.fireStaticEvents('google_ads'); 5181 5182 }, 5183 5184 fireEvent: function (name, data) { 5185 5186 if (!initialized || !this.isEnabled()) { 5187 return false; 5188 } 5189 5190 data.delay = data.delay || 0; 5191 data.params = data.params || {}; 5192 data.ids = data.ids || []; 5193 data.conversion_labels = data.conversion_labels || []; 5194 5195 if (data.delay === 0) { 5196 fireEvent(name, data); 5197 } else { 5198 setTimeout(function (name, data) { 5199 fireEvent(name, data); 5200 }, data.delay * 1000, name, data); 5201 } 5202 5203 return true; 5204 5205 }, 5206 5207 onAdSenseEvent: function (event) { 5208 this.fireEvent(event.name, event); 5209 }, 5210 5211 onClickEvent: function (action, params) { 5212 //disabled 5213 }, 5214 5215 onWatchVideo: function (event) { 5216 this.fireEvent(event.name, event); 5217 }, 5218 5219 onCommentEvent: function (event) { 5220 this.fireEvent(event.name, event); 5221 }, 5222 5223 onFormEvent: function (event) { 5224 this.fireEvent(event.name, event); 5225 }, 5226 5227 onDownloadEvent: function (event) { 5228 this.fireEvent(event.name, event); 5229 }, 5230 5231 5232 5233 5234 onWooAddToCartOnButtonEvent: function (product_id) { 5235 5236 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5237 return; 5238 5239 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5240 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 5241 5242 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]) 5243 Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']['params'].params, event.params) 5244 event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids'] 5245 event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels'] 5246 this.fireEvent(event.name, event); 5247 } 5248 } 5249 5250 }, 5251 5252 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) { 5253 5254 window.pysWooProductData = window.pysWooProductData || []; 5255 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5256 return; 5257 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 5258 5259 if (product_type === Utils.PRODUCT_VARIABLE && !options.google_ads.wooVariableAsSimple) { 5260 product_id = parseInt($form.find('input[name="variation_id"]').val()); 5261 } 5262 5263 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5264 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 5265 5266 Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']["params"], event.params); 5267 event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids'] 5268 event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels'] 5269 5270 var groupValue = 0; 5271 if(product_type === Utils.PRODUCT_GROUPED ) { 5272 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 5273 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 5274 var quantity = parseInt($(this).val()); 5275 if(isNaN(quantity)) { 5276 quantity = 0; 5277 } 5278 5279 var childItem = window.pysWooProductData[product_id]['google_ads'].grouped[childId]; 5280 5281 if(options.woo.addToCartOnButtonValueEnabled && 5282 options.woo.addToCartOnButtonValueOption !== 'global') { 5283
5284 event.params.items.forEach(function(el,index,array) { 5285 if(el.id == childItem.content_id) { 5286 if(quantity > 0){ 5287 el.quantity = quantity; 5288 el.price = childItem.price; 5289 } else { 5290 array.splice(index, 1); 5291 } 5292 } 5293 }); 5294 } 5295 groupValue += childItem.price * quantity; 5296 }); 5297 if(groupValue == 0) return; 5298 event.params.value = groupValue; 5299 } else { 5300 // update items qty param 5301 event.params.items[0].quantity = qty; 5302 } 5303 5304 5305 5306 // maybe customize value option 5307 if (options.woo.addToCartOnButtonValueEnabled && 5308 options.woo.addToCartOnButtonValueOption !== 'global' && 5309 product_type !== Utils.PRODUCT_GROUPED) { 5310 event.params.value = event.params.value * qty; 5311 } 5312 5313 5314 5315 var eventName = is_external ? options.woo.affiliateEventName : event.name; 5316 eventName = normalizeEventName(eventName); 5317 5318 this.fireEvent(eventName, event); 5319 5320 } 5321 } 5322 5323 }, 5324 5325 onWooRemoveFromCartEvent: function (event) { 5326 this.fireEvent(event.name, event); 5327 }, 5328 5329 onWooAffiliateEvent: function (product_id) { 5330 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 5331 return; 5332 var event = options.dynamicEvents.woo_affiliate[this.tag()]; 5333 5334 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5335 if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) { 5336 5337 event = Utils.clone(event) 5338 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params) 5339 this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event); 5340 5341 } 5342 } 5343 5344 }, 5345 5346 onWooPayPalEvent: function (event) { 5347 this.fireEvent(event.name, event); 5348 }, 5349 5350 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 5351 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5352 return; 5353 var event = options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]; 5354 5355 5356 if (window.pysEddProductData.hasOwnProperty(download_id)) { 5357 5358 var index; 5359 5360 if (price_index) { 5361 index = download_id + '_' + price_index; 5362 } else { 5363 index = download_id; 5364 } 5365 5366 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 5367 if (window.pysEddProductData[download_id][index].hasOwnProperty('google_ads')) { 5368 5369 event = Utils.clone(event) 5370 Utils.copyProperties(window.pysEddProductData[download_id][index]['google_ads']['params'], event.params); 5371 event.ids = window.pysEddProductData[download_id][index]['google_ads']['ids'] 5372 // update items qty param 5373 //params.items[0].quantity = qty; 5374 5375 this.fireEvent(event.name, event); 5376 5377 } 5378 } 5379 5380 } 5381 5382 }, 5383 5384 onEddRemoveFromCartEvent: function (event) { 5385 this.fireEvent(event.name, event); 5386 }, 5387 onPageScroll: function (event) { 5388 if (initialized && this.isEnabled()) { 5389 this.fireEvent(event.name, event); 5390 } 5391 }, 5392 onTime: function (event) { 5393 if (initialized && this.isEnabled()) { 5394 this.fireEvent(event.name, event); 5395 } 5396 }, 5397 5398 }; 5399 5400 }(options); 5401 5402 var GTM = function (options) { 5403 5404 var initialized = false; 5405 5406 var datalayer_name = 'dataLayer'; 5407 /* 5408 * @param name 5409 * @param data 5410 */ 5411 function fireEvent(name, event) { 5412 if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) { 5413 return; 5414 } 5415 5416
5417 var eventParams = event.params; 5418 var data = event.params; 5419 var valuesArray = Object.values(event.trackingIds); 5420 var ids = valuesArray.filter(function (pixelId) { 5421 return !Utils.hideMatchingPixel(pixelId, 'gtm'); 5422 }) 5423 Utils.copyProperties(Utils.getRequestParams(), eventParams); 5424 var _fireEvent = function (tracking_id,name,params, event=null) { 5425 5426 var eventData = {}; 5427 var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0; 5428 if(ContainerCodeHasTag) { 5429 params['send_to'] = tracking_id; 5430 } 5431 else if(!options.gtm.gtm_just_data_layer){ 5432 return 5433 } 5434 5435 if (params.hasOwnProperty('ecommerce')) { 5436 eventData.ecommerce = params.ecommerce; 5437 delete params.ecommerce; 5438 } 5439 5440 var automatedParams = { ...params }; 5441 [params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]); 5442 if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) { 5443 eventData.automatedParameters = automatedParams; 5444 } 5445 5446// Move custom parameters to eventData 5447 5448 if (params.hasOwnProperty(params['manualName'])) { 5449 eventData[params['manualName']] = params[params['manualName']]; 5450 delete params[params['manualName']]; 5451 } 5452 5453 ['manualName','triggerType'].forEach(key => { 5454 if (params.hasOwnProperty(key)) { 5455 eventData[key] = params[key]; 5456 delete params[key]; 5457 } 5458 }); 5459 5460 eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 5461 5462 eventData.event = name; 5463 5464 if (options.debug) { 5465 if (ContainerCodeHasTag){ 5466 console.log('[Google GTM #' + tracking_id + '] ' + name, eventData); 5467 } 5468 else { 5469 console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData); 5470 } 5471 } 5472 window[datalayer_name].push(eventData); 5473 5474 var customEvent = new CustomEvent('gtm_event_sent', { 5475 detail: { 5476 eventName: name, 5477 params: eventData, 5478 pixel_ids: tracking_id 5479 } 5480 }); 5481 window.dispatchEvent(customEvent); 5482 5483 }; 5484 5485 var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it 5486 5487 var params = mapParamsToGTM(ids,name,copyParams) 5488 5489 params.event_id = Utils.generateUniqueId(event); 5490 5491 _fireEvent(ids, name, params, event); 5492 } 5493 5494 function normalizeEventName(eventName) { 5495 5496 var matches = { 5497 ViewContent: 'view_item', 5498 AddToCart: 'add_to_cart', 5499 AddToWishList: 'add_to_wishlist', 5500 InitiateCheckout: 'begin_checkout', 5501 Purchase: 'purchase', 5502 Lead: 'generate_lead', 5503 CompleteRegistration: 'sign_up', 5504 AddPaymentInfo: 'set_checkout_option' 5505 }; 5506 5507 return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName; 5508 5509 } 5510 5511 function mapParamsToGTM(tag,name,param) { 5512 var hasGTM = false; 5513 5514 // end 5515 if (Array.isArray(tag)) { 5516 hasGTM = tag.some(function (element) { 5517 return isGTM(element); 5518 }); 5519 } else if(isGTM(tag)) { 5520 hasGTM = true; 5521 } 5522 if(hasGTM) { 5523 delete param.event_category; 5524 delete param.event_label; 5525 5526 delete param.analytics_storage; 5527 delete param.ad_storage; 5528 delete param.ad_user_data; 5529 delete param.ad_personalization; 5530 5531 if(name === 'search') { 5532 param['search'] = param.search_term; 5533 delete param.search_term; 5534 delete param.dynx_itemid; 5535 delete param.dynx_pagetype; 5536 delete param.dynx_totalvalue; 5537 } 5538 } 5539 return param; 5540 } 5541 5542 function isGTM(tag) { 5543 return tag.indexOf('GTM') === 0; 5544 } 5545 /** 5546 * Public API 5547 */ 5548 return { 5549 tag: function() { 5550 return "gtm"; 5551 }, 5552 isEnabled: function () { 5553 return options.hasOwnProperty('gtm'); 5554 }, 5555 getHidePixel: function(){ 5556 if(this.isEnabled() && options.gtm.hasOwnProperty('hide_pixels')) 5557 { 5558 return options.gtm.hide_pixels; 5559 } 5560 return []; 5561 }, 5562 disable: function () { 5563 initialized = false; 5564 }, 5565 updateEnhancedConversionData : function () { 5566 if (!initialized || !this.isEnabled()) { 5567 return; 5568 } 5569 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) { 5570 var advanced = Utils.getAdvancedMergeFormData(true); 5571 if (Object.keys(advanced).length > 0) { 5572 window[datalayer_name].push({'user_data' : advanced}); 5573 } 5574 } 5575 }, 5576 loadPixel: function () { 5577 5578 if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) { 5579 return; 5580 } 5581 datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer'; 5582 5583 for (var i = 0; i < options.gtm.trackingIds.length; i++) { 5584 var trackingId = options.gtm.trackingIds[i]; 5585 if (!Utils.hideMatchingPixel(trackingId, 'gtm') && !options.gtm.gtm_just_data_layer) { 5586 console.log('[PYS] Google Tag Manager container code loaded'); 5587 Utils.loadGTMScript(trackingId); 5588 break; 5589 } 5590 } 5591 5592 if(options.gtm.gtm_just_data_layer) { 5593 console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!"); 5594 console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!"); 5595 if(options.gtm.trackingIds.length == 0){ 5596 Utils.loadGTMScript(); 5597 } 5598 } 5599 5600 if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){ 5601 var advanced = Utils.getAdvancedMergeFormData(true); 5602 if(Object.keys(advanced).length > 0){ 5603 window[datalayer_name].push({'user_data' : advanced}); 5604 } 5605 } 5606 5607 5608 var config = {}; 5609 5610 if(options.user_id && options.user_id != 0) { 5611 config.user_id = options.user_id; 5612 } 5613 5614 // Cross-Domain tracking 5615 5616 var ids = options.gtm.trackingIds.filter(function (pixelId) { 5617 return !Utils.hideMatchingPixel(pixelId, 'gtm'); 5618 }); 5619 5620 5621 initialized = true; 5622 5623 Utils.fireStaticEvents('gtm'); 5624 }, 5625 5626 fireEvent: function (name, data) { 5627 5628 if (!initialized || !this.isEnabled()) { 5629 return false; 5630 } 5631 5632 data.delay = data.delay || 0; 5633 data.params = data.params || {}; 5634 5635 if (data.delay === 0) { 5636 5637 fireEvent(name, data); 5638 5639 } else { 5640 5641 setTimeout(function (name, params) { 5642 fireEvent(name, params); 5643 }, data.delay * 1000, name, data); 5644 5645 } 5646 5647 return true; 5648 5649 }, 5650 5651 onAdSenseEvent: function (event) { 5652 this.fireEvent(event.name, event); 5653 }, 5654 5655 onClickEvent: function (event) { 5656 this.fireEvent(event.name, event); 5657 }, 5658 5659 onWatchVideo: function (event) { 5660 if(!event.hasOwnProperty("youtube_disabled") 5661 || !event.youtube_disabled 5662 || event.params.video_type !== "youtube") { 5663 this.fireEvent(event.name, event); 5664 } 5665 }, 5666 5667 onCommentEvent: function (event) { 5668 5669 this.fireEvent(event.name, event); 5670 5671 }, 5672 5673 onFormEvent: function (event) { 5674 5675 this.fireEvent(event.name, event); 5676 5677 }, 5678 5679 onDownloadEvent: function (event) { 5680 5681 this.fireEvent(event.name, event); 5682 5683 }, 5684 5685 onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) { 5686 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5687 return; 5688 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5689 if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) { 5690 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 5691 Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params) 5692 event.trackingIds = window.pysWooProductData[product_id]['gtm']['trackingIds']; 5693 5694 5695 if(prod_info) 5696 { 5697 item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0]; 5698 5699 if(prod_info['pys_list_name_productlist_id']) 5700 { 5701 item['item_list_id'] = prod_info['pys_list_name_productlist_id'] 5702 } 5703 if(prod_info['pys_list_name_productlist_name']) 5704 { 5705 item['item_list_name'] =prod_info['pys_list_name_productlist_name'] 5706 } 5707 } 5708 this.fireEvent(event.name, event); 5709 } 5710 } 5711 5712 }, 5713 5714 onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) { 5715 window.pysWooProductData = window.pysWooProductData || []; 5716 5717 if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5718 return; 5719 var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]); 5720 5721 if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) { 5722 product_id = parseInt($form.find('input[name="variation_id"]').val()); 5723 } 5724 5725 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5726 if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) { 5727 5728 Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params); 5729 5730 params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params; 5731 5732 if(product_type === Utils.PRODUCT_GROUPED ) { 5733 var groupValue = 0; 5734 $form.find(".woocommerce-grouped-product-list .qty").each(function(index){ 5735 var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]",""); 5736 var quantity = parseInt($(this).val()); 5737 if(isNaN(quantity)) { 5738 quantity = 0; 5739 } 5740 var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId]; 5741
5742 params.items.forEach(function(el,index,array) { 5743 if(el.id == childItem.content_id) { 5744 if(quantity > 0){ 5745 el.quantity = quantity; 5746 el.price = childItem.price; 5747 } else { 5748 array.splice(index, 1); 5749 } 5750 } 5751 }); 5752 groupValue += childItem.price * quantity; 5753 }); 5754 5755 5756 5757 if(options.woo.addToCartOnButtonValueEnabled && 5758 options.woo.addToCartOnButtonValueOption !== 'global' && 5759 params.hasOwnProperty('value')) { 5760 params.value = groupValue; 5761 } 5762 5763 if(groupValue == 0) return; // skip if no items selected 5764 } else { 5765 // update items qty param 5766 params.items[0].quantity = qty; 5767 } 5768 5769 // maybe customize value option 5770 if (options.woo.addToCartOnButtonValueEnabled && 5771 options.woo.addToCartOnButtonValueOption !== 'global' && 5772 product_type !== Utils.PRODUCT_GROUPED) 5773 { 5774 if(params.hasOwnProperty('value')) { 5775 params.value = params.items[0].price * qty; 5776 } 5777 } 5778 5779 if(prod_info) 5780 { 5781 if(prod_info['pys_list_name_productlist_id']) 5782 { 5783 params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id'] 5784 } 5785 if(prod_info['pys_list_name_productlist_name']) 5786 { 5787 params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name'] 5788 } 5789 } 5790 5791 var eventName = is_external ? options.woo.affiliateEventName : event.name; 5792 eventName = normalizeEventName(eventName); 5793 5794 this.fireEvent(eventName, event); 5795 5796 } 5797 } 5798 5799 }, 5800 5801 onWooCheckoutProgressStep: function (event) { 5802 this.fireEvent(event.name, event); 5803 }, 5804 5805 onWooSelectContent: function (event) { 5806 const select_prod_list = {}; 5807 5808 if (event.params.items[0].item_list_name !== undefined) { 5809 select_prod_list.list_name = event.params.items[0].item_list_name; 5810 } 5811 5812 if (event.params.items[0].item_list_id !== undefined) { 5813 select_prod_list.list_id = event.params.items[0].item_list_id; 5814 } 5815 const url = new URL(window.location.href); 5816 select_prod_list.url = url.origin + url.pathname; 5817 Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' }); 5818 this.fireEvent(event.name, event); 5819 }, 5820 5821 onWooRemoveFromCartEvent: function (event) { 5822 this.fireEvent(event.name, event); 5823 }, 5824 5825 onWooAffiliateEvent: function (product_id) { 5826 if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag())) 5827 return; 5828 var event = options.dynamicEvents.woo_affiliate[this.tag()]; 5829 5830 if (window.pysWooProductData.hasOwnProperty(product_id)) { 5831 if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) { 5832 5833 event = Utils.clone(event ); 5834 Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params) 5835 this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event); 5836 5837 } 5838 } 5839 5840 }, 5841 5842 onWooPayPalEvent: function (event) { 5843 this.fireEvent(event.name, event); 5844 }, 5845 5846 onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) { 5847 if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag())) 5848 return; 5849 var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]); 5850 5851 5852 if (window.pysEddProductData.hasOwnProperty(download_id)) { 5853 5854 var index; 5855 5856 if (price_index) { 5857 index = download_id + '_' + price_index; 5858 } else { 5859 index = download_id; 5860 } 5861 5862 if (window.pysEddProductData[download_id].hasOwnProperty(index)) { 5863 if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) { 5864 5865 Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params); 5866 item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0]; 5867 // update items qty param 5868 item.quantity = qty; 5869 5870 this.fireEvent(event.name,event); 5871 5872 } 5873 } 5874 5875 } 5876 5877 }, 5878 5879 onEddRemoveFromCartEvent: function (event) { 5880 this.fireEvent(event.name, event); 5881 }, 5882 5883 onPageScroll: function (event) { 5884 if (initialized && this.isEnabled()) { 5885 this.fireEvent(event.name, event); 5886 } 5887 }, 5888 onTime: function (event) { 5889 if (initialized && this.isEnabled()) { 5890 this.fireEvent(event.name, event); 5891 } 5892 }, 5893 }; 5894 5895 }(options); 5896 5897 var getPixelBySlag = function getPixelBySlag(slug) { 5898 switch (slug) { 5899 case "facebook": return window.pys.Facebook; 5900 case "ga": return window.pys.Analytics; 5901 case "gtm": return window.pys.GTM; 5902 case "google_ads": return window.pys.GAds; 5903 case "bing": return window.pys.Bing; 5904 case "pinterest": return window.pys.Pinterest; 5905 case "tiktok": return window.pys.TikTok; 5906 case "reddit": return window.pys.Reddit; 5907 } 5908 } 5909
5910 window.pys = window.pys || {}; 5911 window.pys.Facebook = Facebook; 5912 window.pys.Analytics = Analytics; 5913 window.pys.GAds = GAds; 5914 window.pys.GTM = GTM; 5915 window.pys.Utils = Utils; 5916 window.pys.TikTok = TikTok; 5917 window.pys.getPixelBySlag = getPixelBySlag; 5918 5919 // Export getPixelBySlag globally for backward compatibility 5920 window.getPixelBySlag = getPixelBySlag; 5921 5922 5923 5924 $(document).ready(function () { 5925 5926 if(Cookies.get('form_track')) 5927 { 5928 Cookies.remove('form_track') 5929 } 5930 5931 if($("#pys_late_event").length > 0) { 5932 var dirAttr = $("#pys_late_event").attr("dir"); 5933 if (dirAttr) { 5934 try { 5935 var events = JSON.parse(dirAttr); 5936 } catch (e) { 5937 console.warn("Invalid JSON in pys_late_event dir attribute:", e); 5938 } 5939 } else { 5940 console.warn("pys_late_event dir attribute is undefined or empty"); 5941 } 5942 if (events) { 5943 for (var platform in events) { 5944 if (events.hasOwnProperty(platform)) { 5945 var platformEvents = events[platform]; 5946 platformEvents.forEach(function (event) { 5947 var eventData = {}; 5948 eventData[event.e_id] = [event]; 5949 if (options.staticEvents.hasOwnProperty(platform)) { 5950 Object.assign(options.staticEvents[platform], eventData); 5951 } else { 5952 options.staticEvents[platform] = eventData; 5953 } 5954 }); 5955 } 5956 } 5957 } 5958 } 5959 5960 var Pinterest = Utils.setupPinterestObject(); 5961 var Bing = Utils.setupBingObject(); 5962 var Reddit = Utils.setupRedditObject(); 5963 if(options.hasOwnProperty('cookie')) 5964 { 5965 if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie) 5966 { 5967 Cookies.remove('pbid') 5968 } 5969 if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie) 5970 { 5971 Cookies.remove('pys_advanced_form_data') 5972 } 5973 5974 if(options.cookie.disabled_landing_page_cookie || !options.enable_lading_page_param || options.cookie.disabled_all_cookie) 5975 { 5976 Cookies.remove('pys_landing_page', { path: '/',domain: domain }) 5977 Cookies.remove('last_pys_landing_page', { path: '/',domain: domain }) 5978 } 5979 if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie) 5980 { 5981 Cookies.remove('pysTrafficSource', { path: '/',domain: domain }) 5982 Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain }) 5983 } 5984 if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie) 5985 { 5986 Cookies.remove('pys_first_visit', { path: '/',domain: domain }) 5987 5988 } 5989 if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie) 5990 { 5991 $.each(Utils.utmTerms, function (index, name) { 5992 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 5993 }); 5994 $.each(Utils.utmTerms, function (index, name) { 5995 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 5996 }); 5997 } 5998 if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie) 5999 { 6000 $.each(Utils.utmId,function(index,name) { 6001 Cookies.remove('pys_' + name, { path: '/',domain: domain }) 6002 }) 6003 $.each(Utils.utmId,function(index,name) { 6004 Cookies.remove('last_pys_' + name, { path: '/',domain: domain }) 6005 }); 6006 } 6007 } 6008 6009 if (options.gdpr.cookie_law_info_integration_enabled) { 6010 var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy'); 6011 6012 if (typeof cli_cookie !== 'undefined') { 6013 if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) { 6014 if (getCookieYes('analytics') === 'yes') { 6015 Utils.manageCookies(); 6016 } 6017 } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') { 6018 Utils.manageCookies(); 6019 } 6020 } 6021 } 6022 6023 if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) { 6024 if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) { 6025 Utils.manageCookies(); 6026 } else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) { 6027 Utils.manageCookies(); 6028 } 6029 } else { 6030 Utils.manageCookies(); 6031 } 6032
6033 Utils.initializeRequestParams(); 6034 Utils.setupGdprCallbacks(); 6035 6036 if ( options.enable_auto_save_advance_matching ) { 6037 let override = options.data_persistency == 'recent_data'; 6038 6039 //Setup Advanced Form Data 6040 if ( options.advance_matching_form.enable_advance_matching_forms ) { 6041 $( document ).on( "blur", "input[type='email']", function () { 6042 let email = $( this ).val().trim().toLowerCase(); 6043 if ( Utils.validateEmail( email ) ) { 6044 Utils.saveAdvancedFormData( email, null, null, null, override ); 6045 } 6046 } ) 6047 $( document ).on( "blur", "input[type='tel']", function () { 6048 let phone = $( this ).val().trim().replace( /\D/g, "" ); 6049 if ( phone.length > 5 ) { 6050 Utils.saveAdvancedFormData( null, phone, null, null, override ); 6051 } 6052 } ) 6053 $( document ).on( "blur", "input[type='text']", function () { 6054 let name; 6055 if ( $( this ).attr( "name" ) && $( this ).attr( "name" ) != '' ) { 6056 name = $( this ).attr( "name" ).trim() 6057 } 6058 if ( name && options.advance_matching_form.advance_matching_fn_names.includes( name ) ) { 6059 let value = $( this ).val().trim(); 6060 if ( value.length > 0 ) { 6061 Utils.saveAdvancedFormData( null, null, value, null, override ); 6062 } 6063 } 6064 if ( name && options.advance_matching_form.advance_matching_ln_names.includes( name ) ) { 6065 let value = $( this ).val().trim(); 6066 if ( value.length > 0 ) { 6067 Utils.saveAdvancedFormData( null, null, null, value, override ); 6068 } 6069 } 6070 if ( name && options.advance_matching_form.advance_matching_tel_names.includes( name ) ) { 6071 let value = $( this ).val().trim(); 6072 if ( value.length > 0 ) { 6073 Utils.saveAdvancedFormData( null, value, null, null, override ); 6074 } 6075 } 6076 if ( name && options.advance_matching_form.advance_matching_em_names.includes( name ) ) { 6077 let email = $( this ).val().trim().toLowerCase(); 6078 6079 if ( Utils.validateEmail( email ) ) { 6080 Utils.saveAdvancedFormData( email, null, null, null, false ); 6081 } 6082 } 6083 } ) 6084 } 6085 6086 //Setup Advanced Url Data 6087 if ( Object.keys( options.advance_matching_url ).length > 0 && options.advance_matching_url.enable_advance_matching_url ) { 6088 const url_params = new URLSearchParams( window.location.search ); 6089 url_params.forEach( ( value, key ) => { 6090 if ( options.advance_matching_url.advance_matching_fn_names.includes( key ) ) { 6091 Utils.saveAdvancedFormData( null, null, value.trim(), null, override ); 6092 } 6093 6094 if ( options.advance_matching_url.advance_matching_ln_names.includes( key ) ) { 6095 Utils.saveAdvancedFormData( null, null, null, value.trim(), override ); 6096 } 6097 6098 if ( options.advance_matching_url.advance_matching_tel_names.includes( key ) ) { 6099 Utils.saveAdvancedFormData( null, value.trim(), null, null, override ); 6100 } 6101 6102 if ( options.advance_matching_url.advance_matching_em_names.includes( key ) ) { 6103 let email = value.trim().toLowerCase() 6104 if ( Utils.validateEmail( email ) ) { 6105 Utils.saveAdvancedFormData( email, null, null, null, override ); 6106 } 6107 } 6108 } ); 6109 } 6110 } 6111 6112 // setup Click Event 6113 if ( 6114 options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") || 6115 options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") || 6116 options.dynamicEvents.hasOwnProperty("automatic_event_tel_link") || 6117 options.dynamicEvents.hasOwnProperty("automatic_event_email_link") || 6118 options.dynamicEvents.hasOwnProperty("automatic_event_download") 6119 ) { 6120 6121 $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) { 6122 6123 var $elem = $(this); 6124 6125 6126 // Download 6127 if(options.dynamicEvents.hasOwnProperty("automatic_event_download")) { 6128 var isFired = false; 6129 if ($elem.is('a')) { 6130 var href = $elem.attr('href'); 6131 if (typeof href !== "string") { 6132 return; 6133 } 6134 href = href.trim(); 6135 var extension = Utils.getLinkExtension(href); 6136 var track_download = false; 6137 6138 if (extension.length > 0) { 6139 6140 if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) { 6141 var pixels = Object.keys(options.dynamicEvents.automatic_event_download); 6142 for (var i = 0; i < pixels.length; i++) { 6143 var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]); 6144 var extensions = event.extensions; 6145 if (extensions.includes(extension)) { 6146 6147 if(pixels[i] == "tiktok" || pixels[i] == "reddit") { 6148 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6149 } else { 6150 if (options.enable_remove_download_url_param) { 6151 href = href.split('?')[0]; 6152 } 6153 event.params.download_url = href; 6154 event.params.download_type = extension; 6155 event.params.download_name = Utils.getLinkFilename(href); 6156 getPixelBySlag(pixels[i]).onDownloadEvent(event); 6157 } 6158 6159 isFired = true; 6160 } 6161 } 6162 } 6163 } 6164 } 6165 if(isFired) { // prevent duplicate events on the same element 6166 return; 6167 } 6168 } 6169 6170 6171 if (!e.hasOwnProperty('originalEvent')) { 6172 return; 6173 } 6174 if($elem.hasClass("add_to_cart_button") || 6175 $elem.hasClass("single_add_to_cart_button") ) { // add_to_cart_button fire in woo 6176 return; 6177 } 6178 6179 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click") 6180 && $elem.hasClass("wcf-next-step-link")) { 6181 return;// add_to_cart_button fire in woo cf 6182 } 6183 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") 6184 && $elem.hasClass("wcf-bump-order-cb")) { 6185 return;// add_to_cart_button fire in woo cf 6186 } 6187 6188 if($elem.hasClass("remove_from_cart_button") ) { // cancel remove from cart 6189 return; 6190 } 6191 if($elem.hasClass("remove") ) { // cancel remove from cart 6192 if($elem.parents('.cart_item').length || $elem.parents('.mini_cart_item').length) 6193 return; 6194 } 6195 if($elem.attr("name") == "update_cart" || $elem.attr("name") == "apply_coupon") { // cancel update c
6195art or coupon button 6196 return; 6197 } 6198 6199 6200 if ($elem.hasClass('pys_block')) { 6201 return; // avoiding fake double clicks from Affiliate event 6202 } 6203 var text = ""; 6204 var target_url = ""; 6205 var linkType = "Internal Click"; 6206 6207 if ($elem.is('a')) { 6208 var href = $elem.attr('href'); 6209 6210 // fixes #112 6211 if (typeof href !== "string") { 6212 return; 6213 } 6214 href = href.trim(); 6215 6216 text = $elem.contents().filter(function() { 6217 return this.nodeType === 3; // ФилÑÑÑÑем ÑолÑко ÑекÑÑовÑе ÑÐ·Ð»Ñ 6218 }).text().trim(); 6219 if(options.enable_remove_target_url_param) { 6220 target_url = href.split('?')[0]; 6221 } else { 6222 target_url = href 6223 } 6224 6225 6226 //Email Event 6227 if ( href.startsWith( 'mailto:' ) ) { 6228 if ( options.triggerEventTypes.hasOwnProperty( "email_link" ) ) { 6229 return; 6230 } else { 6231 setupEmailLinks(); 6232 } 6233 6234 return; // not fire next 6235 } 6236 6237 // Phone 6238 if (href.startsWith('tel:')) { 6239 if(options.dynamicEvents.hasOwnProperty("automatic_event_tel_link")) { 6240 var pixels = Object.keys(options.dynamicEvents.automatic_event_tel_link); 6241 for(var i = 0;i<pixels.length;i++) { 6242 var event = Utils.clone(options.dynamicEvents.automatic_event_tel_link[pixels[i]]); 6243 if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') { 6244 Utils.copyProperties(Utils.getRequestParam
6244s(), event.params); 6245 } 6246 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6247 } 6248 } 6249 return; // not fire next 6250 } 6251 6252 if (href.startsWith('http')) { 6253 // link type 6254 var host = $elem.context != undefined ? $elem.context.host : $elem[0].host; 6255 if (document.location.host != host) { 6256 linkType = 'External Click'; 6257 } 6258 } 6259 } else if ($elem.is('button')) { 6260 if( $elem.hasClass("forminator-button-submit")) { 6261 //disable duplicate events 6262 return; 6263 } 6264 text = $elem.contents().filter(function() { 6265 return this.nodeType === 3; // ФилÑÑÑÑем ÑолÑко ÑекÑÑовÑе ÑÐ·Ð»Ñ 6266 }).text().trim(); 6267 } else if ($elem.is('input[type="button"]')) { 6268 text = $elem.val(); 6269 } else if ($elem.is('input[type="submit"]')) { 6270 if ( $elem.parents("form.comment-form")) { 6271 //disable duplicate events 6272 return; 6273 } 6274 if ($elem.parents("form")) { 6275 //disable duplicate events 6276 return; 6277 } 6278 text = $elem.val(); 6279 } else { 6280 return; 6281 } 6282 6283 6284 6285 text = Utils.filterEmails(text); 6286 6287 6288 if( linkType === "Internal Click" 6289 && options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") 6290 ) { 6291 var pixels = Object.keys(options.dynamicEvents.automatic_event_internal_link); 6292 6293 for(var i = 0;i<pixels.length;i++) { 6294 var event = Utils.clone(options.dynamicEvents.automatic_event_internal_link[pixels[i]]); 6295 6296 if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters 6297 event.params["text"] = text; 6298 if(target_url){ 6299 event.params["target_url"] = target_url; 6300 } 6301 Utils.copyProperties(Utils.getRequestParam
6301s(), event.params); 6302 } 6303 6304 6305 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6306 } 6307 } 6308 6309 if( linkType === "External Click" 6310 && options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") 6311 ) { 6312 var pixels = Object.keys(options.dynamicEvents.automatic_event_outbound_link); 6313 6314 for(var i = 0;i<pixels.length;i++) { 6315 var event = Utils.clone(options.dynamicEvents.automatic_event_outbound_link[pixels[i]]); 6316 6317 if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters 6318 event.params["text"] = text; 6319 if(target_url){ 6320 event.params["target_url"] = target_url; 6321 } 6322 Utils.copyProperties(Utils.getRequestParams(), event.params); 6323 } 6324 6325 6326 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6327 } 6328 } 6329 6330 6331 6332 6333 }); 6334 6335 } 6336 6337 // setup AdSense Event 6338 if (options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) { 6339 6340 var isOverGoogleAd = false; 6341 6342 $(document) 6343 .on('mouseover', 'ins iframe', function () { //class adsbygoogle adsbygoogle-noablate ?? 6344 isOverGoogleAd = true; 6345 }) 6346 .on('mouseout', 'iframe', function () { 6347 isOverGoogleAd = false; 6348 }); 6349 6350 $(window) 6351 .on( "blur",function () { 6352 if (isOverGoogleAd) { 6353 if(options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) { 6354 var pixels = Object.keys(options.dynamicEvents.automatic_event_adsense); 6355 for (var i = 0; i < pixels.length; i++) { 6356 var event = Utils.clone(options.dynamicEvents.automatic_event_adsense[pixels[i]]); 6357 if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') { 6358 Utils.copyProperties(Utils.getRequestParam
6358s(), event.params); 6359 } 6360 getPixelBySlag(pixels[i]).onAdSenseEvent(event); 6361 } 6362 } 6363 6364 $.each(options.triggerEventTypes, function (triggerType, events) { 6365 $.each(events, function (eventId, triggers) { 6366 switch (triggerType) { 6367 case 'ad_sense_click': 6368 Utils.fireTriggerEvent(eventId); 6369 break; 6370 } 6371 }); 6372 }); 6373 } 6374 }) 6375 .trigger("focus"); 6376 6377 } 6378 6379 //setup adsense for custom events 6380 var dynamicAdsenseEventsTriggers = 0 6381 $.each(options.triggerEventTypes, function (triggerType, events) { 6382 if(triggerType == "ad_sense_click") { 6383 dynamicAdsenseEventsTriggers++; 6384 } 6385 }); 6386 if (dynamicAdsenseEventsTriggers > 0) { 6387 6388 var isOverGoogleAd = false; 6389 6390 $(document) 6391 .on('mouseover', 'ins > ins > iframe', function () { 6392 isOverGoogleAd = true; 6393 }) 6394 .on('mouseout', 'iframe', function () { 6395 isOverGoogleAd = false; 6396 }); 6397 6398 $(window) 6399 .on( "blur",function () { 6400 if (isOverGoogleAd) { 6401 6402 $.each(options.triggerEventTypes, function (triggerType, events) { 6403 $.each(events, function (eventId, triggers) { 6404 switch (triggerType) { 6405 case 'ad_sense_click': 6406 Utils.fireTriggerEvent(eventId); 6407 break; 6408 } 6409 }); 6410 }); 6411 } 6412 }) 6413 .trigger("focus"); 6414 6415 } 6416 6417 6418 // page scroll event 6419 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll") 6420 ) { 6421 6422 var singlePageScroll = function () { 6423 6424 6425 var docHeight = $(document).height() - $(window).height(); 6426 var isFired = false; 6427 6428 if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) { 6429 var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll); 6430 for(var i = 0;i<pixels.length;i++) { 6431 var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]); 6432 var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions 6433 6434 if(scroll < $(window).scrollTop()) { 6435 if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') { 6436 Utils.copyProperties(Utils.getRequestParam
6436s(), event.params); 6437 } 6438 getPixelBySlag(pixels[i]).onPageScroll(event); 6439 isFired = true 6440 } 6441 } 6442 } 6443 if(isFired) { 6444 $(document).off("scroll",singlePageScroll); 6445 } 6446 } 6447 $(document).on("scroll",singlePageScroll); 6448 } 6449 6450 6451 if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) { 6452 var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page); 6453 var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel 6454 setTimeout(function(){ 6455 for(var i = 0;i<pixels.length;i++) { 6456 var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]); 6457 if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') { 6458 Utils.copyProperties(Utils.getRequestParam
6458s(), event.params); 6459 } 6460 getPixelBySlag(pixels[i]).onTime(event); 6461 } 6462 },time*1000); 6463 } 6464 6465 // setup Dynamic events 6466 6467 $.each(options.triggerEventTypes, function (triggerType, events) { 6468 6469 $.each(events, function (eventId, triggers) { 6470 switch (triggerType) { 6471 case 'url_click': 6472 //@see: Utils.setupURLClickEvents() 6473 break; 6474 6475 case 'css_click': 6476 Utils.setupCSSClickEvents(eventId, triggers); 6477 break; 6478 6479 case 'css_mouseover': 6480 Utils.setupMouseOverClickEvents(eventId, triggers); 6481 break; 6482 6483 case 'scroll_pos': 6484 Utils.setupScrollPosEvents(eventId, triggers); 6485 break; 6486 case 'comment': 6487 Utils.setupCommentEvents(eventId, triggers); 6488 break; 6489 case 'video_view': 6490 //@see: Utils.checkYouTubeCompletion() and Utils.addYouTubeEvents() 6491 break; 6492 6493 case 'form_field': 6494 Utils.setupFormFieldEvents(eventId, triggers); 6495 break; 6496 } 6497 6498 }); 6499 6500 if ( triggerType == "email_link" ) { 6501 Utils.setupEmailLinkEvents( events ) 6502 } 6503 6504 }); 6505 6506 // setup WooCommerce events 6507 if (options.woo.enabled) { 6508 6509 // Woo CartFlow AddToCart 6510 if (options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")) { 6511 $("body").on("click",'.wcf-next-step-link',function () { 6512 var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_next_step_click); 6513 for(var i = 0;i<pixels.length;i++) { 6514 var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_next_step_click[pixels[i]]) 6515 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6516 } 6517 }); 6518 } 6519 // Woo CartFlow Bump AddToCart 6520 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") || 6521 options.dynamicEvents.hasOwnProperty("wcf_bump")) { 6522 $("body").on('change','.wcf-bump-order-cb',function () { 6523 6524 if(this.checked) { 6525 if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")) { 6526 var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_bump_click); 6527 for(var i = 0;i<pixels.length;i++) { 6528 var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_bump_click[pixels[i]]); 6529 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6530 } 6531 } 6532 6533 6534 if(options.dynamicEvents.hasOwnProperty("wcf_bump")) { 6535 var pixels = Object.keys(options.dynamicEvents.wcf_bump); 6536 for(var i = 0;i<pixels.length;i++) { 6537 var event = Utils.clone(options.dynamicEvents.wcf_bump[pixels[i]]); 6538 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6539 } 6540 } 6541 6542 } else { 6543 if(options.dynamicEvents.hasOwnProperty("wcf_remove_from_cart_on_bump_click")) { 6544 var pixels = Object.keys(options.dynamicEvents.wcf_remove_from_cart_on_bump_click); 6545 for(var i = 0;i<pixels.length;i++) { 6546 var event = Utils.clone(options.dynamicEvents.wcf_remove_from_cart_on_bump_click[pixels[i]]); 6547 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 6548 } 6549 } 6550 6551 } 6552 6553 6554 }); 6555 } 6556 6557 6558 // WooCommerce AddToCart 6559 if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click") 6560 && options.woo.hasOwnProperty("addToCartCatchMethod") 6561 && options.woo.addToCartCatchMethod === "add_cart_js" 6562 ) { 6563 // Loop, any kind of "simple" product, except external 6564 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 6565 6566 var $button = $(this); 6567 var $prod_info = $button.siblings('.pys_list_name_productdata').data(); 6568 var product_id = $(this).data('product_id'); 6569 Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' }) 6570 var product_id = $(this).data('product_id'); 6571 if (typeof product_id !== 'undefined') { 6572 6573 if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){ 6574 var tmpEventID = pys_generate_token(); 6575 $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) { 6576 tag.eventID = tmpEventID; 6577 }); 6578 } 6579 6580 Facebook.onWooAddToCartOnButtonEvent(product_id,$(this)); 6581 Analytics.onWooAddToCartOnButtonEvent(product_id, $prod_info); 6582 GTM.onWooAddToCartOnButtonEvent(product_id, $prod_info); 6583 GAds.onWooAddToCartOnButtonEvent(product_id); 6584 Pinterest.onWooAddToCartOnButtonEvent(product_id); 6585 Bing.onWooAddToCartOnButtonEvent(product_id); 6586 TikTok.onWooAddToCartOnButtonEvent(product_id); 6587 Reddit.onWooAddToCartOnButtonEvent(product_id); 6588 } 6589 6590 }); 6591 6592 // Single Product 6593 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 6594 // $(document) not work 6595 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 6596 6597 var $button = $(this); 6598 var $prod_info = $button.siblings('.pys_list_name_productdata').data(); 6599 var product_id = $(this).data('product_id'); 6600 Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' }) 6601 if ($button.hasClass('disabled')) { 6602 return; 6603 } 6604 6605 var $form = $button.closest('form'); 6606 6607 var product_type = Utils.PRODUCT_SIMPLE; 6608 var is_external = false; 6609 6610 if ($form.length === 0) { 6611 is_external = true; 6612 } else if ($form.hasClass('variations_form')) { 6613 product_type = Utils.PRODUCT_VARIABLE; 6614 } else if($form.hasClass('bundle_form')) { 6615 product_type = Utils.PRODUCT_BUNDLE; 6616 } else if($form.hasClass('grouped_form')) { 6617 product_type = Utils.PRODUCT_GROUPED; 6618 } 6619 6620 6621 6622 var product_id; 6623 var qty; 6624 if (product_type === Utils.PRODUCT_GROUPED) { 6625 qty = 1; 6626 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 6627 } else if (product_type === Utils.PRODUCT_VARIABLE) { 6628 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 6629 var qtyTag = $form.find('input[name="quantity"]'); 6630 if(qtyTag.length <= 0) { 6631 qtyTag = $form.find('select[name="quantity"]'); 6632 } 6633 qty = parseInt(qtyTag.val()); 6634 } else if (is_external) { 6635 product_id = options.woo.singleProductId; 6636 qty = 1; 6637 } else { 6638 product_id = parseInt($form.find('*[name="add-to-cart"]').val()); 6639 var qtyTag = $form.find('input[name="quantity"]'); 6640 if(qtyTag.length <= 0) { 6641 qtyTag = $form.find('select[name="quantity"]'); 6642 } 6643 qty = parseInt(qtyTag.val()); 6644 } 6645 6646 // 6647 if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){ 6648 var tmpEventID = pys_generate_token(); 6649 $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) { 6650 tag.eventID = tmpEventID; 6651 }); 6652 } 6653 6654 Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6655 Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info); 6656 GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info); 6657 GAds.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6658 Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6659 Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6660 TikTok.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6661 Reddit.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form); 6662 }); 6663 6664 } else { 6665 $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) { 6666 var $button = $(this); 6667 var $prod_info = $button.siblings('.pys_list_name_productdata').data(); 6668 var product_id = $(this).data('product_id'); 6669 Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' }) 6670 }); 6671 6672 // Single Product 6673 // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it 6674 // $(document) not work 6675 $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) { 6676 6677 var $button = $(this); 6678 var $prod_info = $button.siblings('.pys_list_name_productdata').data(); 6679 Cookies.set('productlist', $prod_info, { expires: 1,path: '/' }) 6680 }); 6681 } 6682 6683 // WooCommerce Affiliate 6684 if (options.dynamicEvents.hasOwnProperty("woo_affiliate")) { 6685 6686 // Loop, external 6687 $('.product_type_external').on("click",function (e) { 6688 6689 var product_id = $(this).data('product_id'); 6690 6691 if (typeof product_id !== 'undefined') { 6692 Facebook.onWooAffiliateEvent(product_id); 6693 Analytics.onWooAffiliateEvent(product_id); 6694 GTM.onWooAffiliateEvent(product_id); 6695 GAds.onWooAffiliateEvent(product_id); 6696 Pinterest.onWooAffiliateEvent(product_id); 6697 Bing.onWooAffiliateEvent(product_id); 6698 } 6699 6700 }); 6701 6702 } 6703 6704 // WooCommerce RemoveFromCart 6705 if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) { 6706 6707 $('body').on('click', options.woo.removeFromCartSelector, function (e) { 6708 6709 var $a = $(e.currentTarget), 6710 href = $a.attr('href'); 6711 6712 // extract cart item hash from remove button URL 6713 var regex = new RegExp("[\\?&]remove_item=([^&#]*)"), 6714 results = regex.exec(href); 6715 6716 if (results !== null) { 6717 6718 var item_hash = results[1]; 6719 6720 if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) { 6721 var events = options.dynamicEvents["woo_remove_from_cart"][item_hash]; 6722 Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events) 6723 } 6724 6725 } 6726 6727 }); 6728 6729 } 6730 6731 // WooCommerce PayPal 6732 if (options.dynamicEvents.hasOwnProperty("woo_paypal")) { 6733 6734 // Non-default binding used to avoid situations when some code in external js 6735 // stopping events propagation, eg. returns false, and our handler will never called 6736 $(document).onFirst('submit click', '#place_order', function (e) { 6737 6738 var method = $('form[name="checkout"] input[name="payment_method"]:checked').val(); 6739 6740 if (method !== 'paypal') { 6741 return; 6742 } 6743 var events = options.dynamicEvents.woo_paypal; 6744 Utils.fireEventForAllPixel("onWooPayPalEvent",events) 6745 6746 }); 6747 6748 } 6749 6750 // WooCommerce checkout progress 6751 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_f") ) { 6752 6753 $(document).on("change",".woocommerce-validated #billing_first_name",function () { 6754 var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_f); 6755 for (var i = 0; i < pixels.length; i++) { 6756 var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_f[pixels[i]]); 6757 getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event); 6758 } 6759 }); 6760 } 6761 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_l")) { 6762 6763 $(document).on("change",".woocommerce-validated #billing_last_name",function () { 6764 var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_l); 6765 for (var i = 0; i < pixels.length; i++) { 6766 var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_l[pixels[i]]); 6767 getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event); 6768 } 6769 }); 6770 } 6771 6772 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_e")) { 6773 6774 $(document).on("change",".woocommerce-validated #billing_email",function () { 6775 var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_e); 6776 for (var i = 0; i < pixels.length; i++) { 6777 var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_e[pixels[i]]); 6778 getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event); 6779 } 6780 }); 6781 } 6782 if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_o")) { 6783 $(document).onFirst('submit click', '#place_order', function () { 6784 var shippingMethodFull = $('[name="shipping_method[0]"]:checked').val(); 6785 var shippingMethod = shippingMethodFull ? shippingMethodFull.split(':')[0] : ''; 6786 var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_o); 6787
6787 for (var i = 0; i < pixels.length; i++) { 6788 var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_o[pixels[i]]); 6789 // Add shipping_method to event params 6790 event.params = event.params || {}; 6791 event.params.checkout_option = shippingMethod; 6792 getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event); 6793 } 6794 }); 6795 } 6796 6797 6798 // WooCommerce 6799 6800 $('.product.type-product a.woocommerce-loop-product__link').onFirst('click', function (evt) { 6801 var productId = $(this).closest('.product').find(".add_to_cart_button").attr("data-product_id"); 6802 var eventTypes = ["woo_select_content_search", "woo_select_content_shop", "woo_select_content_tag", "woo_select_content_single", "woo_select_content_category"]; 6803 var isEventFired = false; 6804 6805 for (var i = 0; i < eventTypes.length; i++) { 6806 var eventType = eventTypes[i]; 6807 if (options.dynamicEvents.hasOwnProperty(eventType) && options.dynamicEvents[eventType].hasOwnProperty(productId)) { 6808 if(Analytics.isEnabled()){ 6809 Analytics.onWooSelectContent(options.dynamicEvents[eventType][productId][Analytics.tag()]); 6810 } 6811 if(GTM.isEnabled()){ 6812 GTM.onWooSelectContent(options.dynamicEvents[eventType][productId][GTM.tag()]); 6813 } 6814 isEventFired = true; 6815 break; 6816 } 6817 } 6818 6819 if (!isEventFired) { 6820 let prod_info = $(this).parent().find('.pys_list_name_productdata').data(); 6821 if (prod_info) { 6822 const select_prod_list = {}; 6823 if (prod_info['pys_list_name_productlist_name']) { 6824 select_prod_list.list_name = prod_info['pys_list_name_productlist_name'] 6825 } 6826 if (prod_info['pys_list_name_productlist_id']) { 6827 select_prod_list.list_id = prod_info['pys_list_name_productlist_id'] 6828 } 6829 const url = new URL(window.location.href); 6830 select_prod_list.url = url.origin + url.pathname; 6831 Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' }); 6832 } 6833 } 6834 }); 6835 6836 } 6837 6838 // setup EDD events 6839 if (options.edd.enabled) { 6840 6841 // EDD AddToCart 6842 if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) { 6843 6844 $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) { 6845 6846 var $button = $(this); 6847 var $form = $button.closest('form'); 6848 var variable_price = $button.data('variablePrice'); // yes/no 6849 var price_mode = $button.data('priceMode'); // single/multi 6850 var ids = []; 6851 var quantities = []; 6852 var qty; 6853 var id; 6854 6855 if (variable_price === 'yes' && price_mode === 'multi') { 6856 6857 id = $form.find('input[name="download_id"]').val(); 6858 6859 // get selected variants 6860 $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) { 6861 ids.push(id + '_' + $(el).val()); 6862 }); 6863 6864 // get qty for selected variants 6865 $.each(ids, function (i, variant_id) { 6866 6867 var variant_index = variant_id.split('_', 2); 6868 qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val(); 6869 6870 if (typeof qty !== 'undefined') { 6871 quantities.push(qty); 6872 } else { 6873 quantities.push(1); 6874 } 6875 6876 }); 6877 6878 } else if (variable_price === 'yes' && price_mode === 'single') { 6879 6880 id = $form.find('input[name="download_id"]').val(); 6881 ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val()); 6882 6883 qty = $form.find('input[name="edd_download_quantity"]').val(); 6884 6885 if (typeof qty !== 'undefined') { 6886 quantities.push(qty); 6887 } else { 6888 quantities.push(1); 6889 } 6890 6891 } else { 6892 6893 ids.push($button.data('downloadId')); 6894 6895 qty = $form.find('input[name="edd_download_quantity"]').val(); 6896 6897 if (typeof qty !== 'undefined') { 6898 quantities.push(qty); 6899 } else { 6900 quantities.push(1); 6901 } 6902 } 6903 6904 // fire event for each download/variant 6905 $.each(ids, function (i, download_id) { 6906 6907 var q = parseInt(quantities[i]); 6908 var variant_index = download_id.toString().split('_', 2); 6909 var price_index; 6910 6911 if (variant_index.length === 2) { 6912 download_id = variant_index[0]; 6913 price_index = variant_index[1]; 6914 } 6915 6916 Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6917 Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6918 GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6919 GAds.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6920 Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6921 Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6922 TikTok.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6923 Reddit.onEddAddToCartOnButtonEvent(download_id, price_index, q); 6924 6925 }); 6926 6927 }); 6928 6929 } 6930 6931 // EDD RemoveFromCart 6932 if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) { 6933 6934 $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) { 6935 6936 var href = $(this).attr('href'); 6937 var key = href.substring(href.indexOf('=') + 1).charAt(0);
6938 6939 if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) { 6940 var events = options.dynamicEvents.edd_remove_from_cart[key]; 6941 Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events) 6942 } 6943 6944 }); 6945 6946 } 6947 6948 } 6949 6950 Utils.setupURLClickEvents(); 6951 6952 // setup Comment Event 6953 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment") 6954 ) { 6955 6956 $('form.comment-form').on("submit",function () { 6957 if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) { 6958 var pixels = Object.keys(options.dynamicEvents.automatic_event_comment); 6959 for (var i = 0; i < pixels.length; i++) { 6960 var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]); 6961 if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') { 6962 Utils.copyProperties(Utils.getRequestParam
6962s(), event.params); 6963 } 6964 getPixelBySlag(pixels[i]).onCommentEvent(event); 6965 } 6966 } 6967 }); 6968 6969 } 6970 6971 // setup Form Event 6972 if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 6973 6974 $(document).onFirst('submit', 'form', function (e) { 6975 6976 var $form = $(this); 6977 6978 // exclude WP forms 6979 if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') { 6980 return; 6981 } 6982 6983 // exclude Woo forms 6984 if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') || 6985 $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) { 6986 return; 6987 } 6988 6989 // exclude EDD forms 6990 if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) { 6991 return; 6992 } 6993 // exclude CF7 forms 6994 if ($form.hasClass('wpcf7-form')) { 6995 return; 6996 } 6997 // exclude Gravity forms 6998 if ($form.attr('id') && $form.attr('id').includes('gform')) { 6999 var target = $form.attr('target'); 7000 if (target && target.indexOf('gform_ajax_frame') !== -1) { 7001 return; 7002 } 7003 } 7004 // exclude Forminator forms 7005 if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) { 7006 return; 7007 } 7008 // exclude WPforms forms 7009 if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) { 7010 return; 7011 } 7012 // exclude Formidable forms 7013 /*if ($form.hasClass('frm-show-form')) { 7014 return; 7015 }*/ 7016 // exclude Ninja Forms forms 7017 if ($form.parent().hasClass('nf-form-layout')) { 7018 return; 7019 } 7020 // exclude Fluent forms 7021 if ($form.hasClass('frm-fluent-form')) { 7022 return; 7023 } 7024 7025 // exclude WS form forms 7026 if ($form.hasClass('wsf-form') ) { 7027 return; 7028 } 7029 7030 // exclude WS form forms 7031 if ( $form.hasClass( 'elementor-form' ) ) { 7032 return; 7033 } 7034 7035 if(!options.enable_success_send_form) { 7036 var params = { 7037 form_id: $form.attr('id'), 7038 form_class: $form.attr('class') ? $form.attr('class') : $form.attr('id'), 7039 text: $form.find('[type="submit"]').is('input') ? 7040 $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text() 7041 }; 7042 7043 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 7044 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 7045 for (var i = 0; i < pixels.length; i++) { 7046 var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]); 7047 7048 if (pixels[i] === "tiktok" || pixels[i] === "reddit") { 7049 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 7050 } else { 7051 Utils.copyProperties(params, event.params,) 7052 Utils.copyProperties(Utils.getRequestParam
7052s(), event.params); 7053 getPixelBySlag(pixels[i]).onFormEvent(event); 7054 } 7055 } 7056 } 7057 } 7058 }); 7059 7060 7061 } 7062 7063 jQuery(document).on('elementor/popup/show', function(event) { 7064 for (var i = 0; i < jQuery(".wpcf7-form").length; i++) { 7065 wpcf7.init(jQuery(".wpcf7-form")[i]); 7066 } 7067 }); 7068 7069 document.addEventListener( 'wpcf7mailsent', function ( event ) { 7070 let form_id = event.detail.contactFormId, 7071 sendEventId = null, 7072 disabled_form_action = false, 7073 form_submit_mode = 'both'; 7074 if ( options.triggerEventTypes.hasOwnProperty( 'CF7' ) ) { 7075 $.each( options.triggerEventTypes.CF7, function ( eventId, triggers ) { 7076 $.each( triggers, function ( index, trigger ) { 7077 $.each( trigger.forms, function ( i, value ) { 7078 if ( value == form_id ) { 7079 sendEventId = eventId; 7080 disabled_form_action = trigger.disabled_form_action; 7081 form_submit_mode = trigger.form_submit_mode || 'both'; 7082 } 7083 } ) 7084 } ); 7085 } ); 7086 } 7087 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7088 Utils.fireTriggerEvent( sendEventId ); 7089 } 7090 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7091 7092 }, false ); 7093 7094 //GravityForm 7095 jQuery( document ).on( 'gform_confirmation_loaded', function ( event, formId ) { 7096 let form_id = formId, 7097 sendEventId = null, 7098 disabled_form_action = false, 7099 form_submit_mode = 'both'; 7100 if ( options.triggerEventTypes.hasOwnProperty( 'gravity' ) ) { 7101 $.each( options.triggerEventTypes.gravity, function ( eventId, triggers ) { 7102 $.each( triggers, function ( index, trigger ) { 7103 $.each( trigger.forms, function ( i, value ) { 7104 if ( value == form_id ) { 7105 disabled_form_action = trigger.disabled_form_action; 7106 sendEventId = eventId; 7107 form_submit_mode = trigger.form_submit_mode || 'both'; 7108 } 7109 } ) 7110 } ); 7111 } ); 7112 } 7113 7114 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7115 Utils.fireTriggerEvent( sendEventId ); 7116 } 7117 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7118 jQuery( document ).off( 'gform_confirmation_loaded' ); 7119 } ); 7120 //Forminator 7121 $( document ).on( 'forminator:form:submit:success', function ( event ) { 7122 7123 let form_id = $( event.target ).find( 'input[name="form_id"]' ).val(), 7124 sendEventId = null, 7125 disabled_form_action = false, 7126 form_submit_mode = 'both'; 7127 if ( options.triggerEventTypes.hasOwnProperty( 'forminator' ) ) { 7128 $.each( options.triggerEventTypes.forminator, function ( eventId, triggers ) { 7129 $.each( triggers, function ( index, trigger ) { 7130 $.each( trigger.forms, function ( i, value ) { 7131 if ( value == form_id ) { 7132 disabled_form_action = trigger.disabled_form_action; 7133 sendEventId = eventId; 7134 form_submit_mode = trigger.form_submit_mode || 'both'; 7135 } 7136 } ) 7137 } ); 7138 } ); 7139 } 7140 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7141 Utils.fireTriggerEvent( sendEventId ); 7142 } 7143 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7144 } ); 7145 7146 //WPForm 7147 $( 'form.wpforms-form' ).on( 'wpformsAjaxSubmitSuccess', ( event ) => { 7148 7149 let form_id = $( event.target ).attr( 'data-formid' ), 7150 sendEventId = null, 7151 disabled_form_action = false, 7152 form_submit_mode = 'both'; 7153 7154 if ( options.triggerEventTypes.hasOwnProperty( 'wpforms' ) ) { 7155 $.each( options.triggerEventTypes.wpforms, function ( eventId, triggers ) { 7156 $.each( triggers, function ( index, trigger ) { 7157 $.each( trigger.forms, function ( i, value ) { 7158 if ( value == form_id ) { 7159 sendEventId = eventId; 7160 disabled_form_action = trigger.disabled_form_action; 7161 form_submit_mode = trigger.form_submit_mode || 'both'; 7162 } 7163 } ) 7164 } ); 7165 } ); 7166 } 7167 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7168 Utils.fireTriggerEvent( sendEventId ); 7169 } 7170 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7171 } ) 7172 7173 $( document ).on( 'frmFormComplete', function ( event, form, response ) { 7174 const form_id = $( form ).find( 'input[name="form_id"]' ).val(); 7175 let sendEventId = null, 7176 disabled_form_action = false, 7177 form_submit_mode = 'both'; 7178 if ( options.triggerEventTypes.hasOwnProperty( 'formidable' ) ) { 7179 $.each( options.triggerEventTypes.formidable, function ( eventId, triggers ) { 7180 $.each( triggers, function ( index, trigger ) { 7181 $.each( trigger.forms, function ( i, value ) { 7182 if ( value == form_id ) { 7183 disabled_form_action = trigger.disabled_form_action; 7184 sendEventId = eventId; 7185 form_submit_mode = trigger.form_submit_mode || 'both'; 7186 } 7187 } ) 7188 } ); 7189 } ); 7190 } 7191 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7192 Utils.fireTriggerEvent( sendEventId ); 7193 } 7194 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7195 7196 } ); 7197 7198 // Ninja Forms 7199 $( document ).onFirst( 'nfFormSubmitResponse', function ( event, data ) { 7200 const form_id = data.response.data.form_id; 7201 let sendEventId = null, 7202 disabled_form_action = false, 7203 form_submit_mode = 'both'; 7204 if ( options.triggerEventTypes.hasOwnProperty( 'ninjaform' ) ) { 7205 $.each( options.triggerEventTypes.ninjaform, function ( eventId, triggers ) { 7206 $.each( triggers, function ( index, trigger ) { 7207 $.each( trigger.forms, function ( i, value ) { 7208 if ( value == form_id ) { 7209 disabled_form_action = trigger.disabled_form_action; 7210 sendEventId = eventId; 7211 form_submit_mode = trigger.form_submit_mode || 'both'; 7212 } 7213 } ) 7214 } ); 7215 } ); 7216 } 7217 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7218 Utils.fireTriggerEvent( sendEventId ); 7219 } 7220 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7221 } ); 7222 7223 7224 $(document).on('fluentform_submission_success', function ( event, data ) { 7225 if(!data || !data.form){ 7226 return; 7227 } 7228 let $form = data.form; // Submitted form 7229 let config = data.config; // Form configuration 7230 let response = data.response; // Server response 7231 7232 7233 let $formItem = $form; 7234 let form_id = config.id; 7235 let sendEventId = null, 7236 disabled_form_action = false, 7237 form_submit_mode = 'both'; 7238 if ( options.triggerEventTypes.hasOwnProperty( 'fluentform' ) ) { 7239 $.each( options.triggerEventTypes.fluentform, function ( eventId, triggers ) { 7240 $.each( triggers, function ( index, trigger ) { 7241 $.each( trigger.forms, function ( i, value ) { 7242 if ( value == form_id ) { 7243 disabled_form_action = trigger.disabled_form_action; 7244 sendEventId = eventId; 7245 form_submit_mode = trigger.form_submit_mode || 'both'; 7246 } 7247 } ) 7248 } ); 7249 } ); 7250 } 7251 7252 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7253 Utils.fireTriggerEvent( sendEventId ); 7254 } 7255 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7256 } ); 7257 7258 //WSForm 7259 $( document ).on( 'wsf-submit-complete', ( event, form_object, form_id ) => { 7260 let sendEventId = null, 7261 disabled_form_action = false, 7262 form_submit_mode = 'both'; 7263 if ( options.triggerEventTypes.hasOwnProperty( 'wsform' ) ) { 7264 $.each( options.triggerEventTypes.wsform, function ( eventId, triggers ) { 7265 $.each( triggers, function ( index, trigger ) { 7266 $.each( trigger.forms, function ( i, value ) { 7267 if ( value == form_id ) { 7268 disabled_form_action = trigger.disabled_form_action; 7269 sendEventId = eventId; 7270 form_submit_mode = trigger.form_submit_mode || 'both'; 7271 } 7272 } ) 7273 } ); 7274 } ); 7275 } 7276 7277 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7278 Utils.fireTriggerEvent( sendEventId ); 7279 } 7280 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7281 } ) 7282 7283 // Elementor Forms 7284 let forms = document.querySelectorAll( '.elementor-form' ); 7285 // Apply the observer to each form
7286 forms.forEach( function ( form ) { 7287 observeElementorForm( form ); 7288 } ); 7289 7290 // watching Elementor Popup forms 7291 let observer = new MutationObserver( function ( mutationsList, observer ) { 7292 for ( let i = 0; i < mutationsList.length; i++ ) { 7293 let popupForm = document.querySelector( '[class*="elementor-popup"] form' ); 7294 if ( popupForm ) { 7295 observeElementorForm( popupForm ); 7296 observer.disconnect(); 7297 break; 7298 } 7299 } 7300 } ); 7301 observer.observe( document.body, { childList: true, subtree: true } ); 7302 7303 // load pixel APIs 7304 Utils.loadPixels(); 7305 7306 // setup Enrich content 7307 if(Utils.isCheckoutPage()) { 7308 Utils.addCheckoutFields(); 7309 } 7310 if(options.woo.hasOwnProperty('woo_view_content_variation_is_selected') && options.woo.woo_view_content_variation_is_selected) { 7311 handleWooViewContentVariation() 7312 } 7313 7314 }); 7315 7316 7317 function handleWooViewContentVariation() { 7318 var form = $('form.variations_form'); 7319 7320 form.on('change', 'select', function() { 7321 var selectedAttributes = {}; 7322 form.find('select').each(function() { 7323 var attributeName = $(this).data('attribute_name') || $(this).attr('name'); 7324 var attributeValue = $(this).val(); 7325 if (attributeValue) { 7326 selectedAttributes[attributeName] = attributeValue; 7327 } 7328 }); 7329 7330 $.ajax({
7331 url: options.ajaxUrl, 7332 type: 'POST', 7333 data: { 7334 action: 'get_variation_info', 7335 product_id: form.data('product_id'), // ÐеÑедаем ID оÑновного ÑоваÑа 7336 attributes: selectedAttributes 7337 }, 7338 success: function(response) { 7339 if (response.success) { 7340 $.each(response.data, function(slug) { 7341 $.each(response.data[slug], function(index, event) { 7342 event.isVariationTrigger = true; 7343 getPixelBySlag(slug).fireEvent(event.name, event); 7344 }); 7345 }); 7346 } else { 7347 console.log('Error retrieving data:', response.data); 7348 } 7349 } 7350 }); 7351 }); 7352 } 7353 var sendFormAction = function (form_target, formId, customEventId = null, disabled = false, form_submit_mode = 'both'){ 7354 // Check submit mode - skip automatic event if reload_only 7355 if (disabled == true || form_submit_mode === 'reload_only' ) { 7356 return; 7357 } 7358 7359 var params = { 7360 form_id: formId, 7361 text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() : 7362 form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() : 7363 form_target.find('[type="submit"]').text() 7364 }; 7365 7366 if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) { 7367 var pixels = Object.keys(options.dynamicEvents.automatic_event_form); 7368 for (var i = 0; i < pixels.length; i++) { 7369 7370 if ( disabled && customEventId && typeof options.triggerEvents[customEventId][pixels[i]] !== 'undefined') { 7371 continue; 7372 } 7373 var event = options.dynamicEvents.automatic_event_form[pixels[i]]; 7374 if (pixels[i] === "tiktok" || pixels[i] === "reddit") { 7375 getPixelBySlag(pixels[i]).fireEvent(event.name, event); 7376 } else { 7377 Utils.copyProperties(params, event.params)
7378 Utils.copyProperties(Utils.getRequestParams(), event.params); 7379 getPixelBySlag(pixels[i]).onFormEvent(event); 7380 } 7381 } 7382 } 7383 } 7384 7385 var setupEmailLinks = function ( disabled_for_pixels = [] ) { 7386 if ( options.dynamicEvents.hasOwnProperty( "automatic_event_email_link" ) ) { 7387 var pixels = Object.keys( options.dynamicEvents.automatic_event_email_link ); 7388 for ( var i = 0; i < pixels.length; i++ ) { 7389 if ( disabled_for_pixels.indexOf(pixels[ i ]) === -1 ) { 7390 var event = Utils.clone( options.dynamicEvents.automatic_event_email_link[ pixels[ i ] ] ); 7391 if ( pixels[ i ] !== 'tiktok' && pixels[ i ] !== 'reddit' ) { 7392 Utils.copyProperties( Utils.getRequestParams(), event.params ); 7393 } 7394 getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event ); 7395 } 7396 } 7397 } 7398 } 7399 7400 //Elementor Forms Observer 7401 var observeElementorForm = function ( form ) { 7402 let observer = new MutationObserver( function ( mutations ) { 7403 7404 for ( let i = 0; i < mutations.length; i++ ) { 7405 let mutation = mutations[ i ]; 7406 7407 if ( mutation.type === 'childList' || mutation.type === 'attributes' ) { 7408 if ( $( form ).find( '.elementor-message-success' ).length > 0 ) { 7409 7410 let form_id = $( form ).attr( 'id' ); 7411 if ( !form_id ) { 7412 form_id = $( form ).find( 'input[name="form_id"]' ).val(); 7413 } 7414 7415 let sendEventId = null, 7416 disabled_form_action = false, 7417 form_submit_mode = 'both'; 7418 if ( options.triggerEventTypes.hasOwnProperty( 'elementor_form' ) ) { 7419 $.each( options.triggerEventTypes.elementor_form, function ( eventId, triggers ) { 7420 $.each( triggers, function ( index, trigger ) { 7421 $.each( trigger.forms, function ( i, value ) { 7422 if ( value == form_id ) { 7423 disabled_form_action = trigger.disabled_form_action; 7424 sendEventId = eventId; 7425 form_submit_mode = trigger.form_submit_mode || 'both'; 7426 } 7427 }) 7428 } ); 7429 } ); 7430 } 7431 if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) { 7432 Utils.fireTriggerEvent( sendEventId ); 7433 } 7434 sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode ); 7435 7436 observer.disconnect(); 7437 break; 7438 } 7439 } 7440 } 7441 } ); 7442 7443 // Start observing the form for changes 7444 observer.observe( form, { 7445 attributes: true, 7446 childList: true, 7447 subtree: true 7448 } ); 7449 } 7450 7451}(jQuery, pysOptions); 7452 7453 7454function pys_generate_token() { 7455 return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => 7456 (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) 7457 ); 7458} 7459function getBundlePriceOnSingleProduct(data) { 7460 var items_sum = 0; 7461 jQuery(".bundle_form .bundled_product").each(function(index){ 7462 var id = jQuery(this).find(".cart").data("bundled_item_id"); 7463 var item_price = data.prices[id]; 7464 var item_quantity = jQuery(this).find(".bundled_qty").val(); 7465 if(!jQuery(this).hasClass("bundled_item_optional") || 7466 jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) { 7467 items_sum += item_price*item_quantity; 7468 } 7469 });
7470 return items_sum; 7471} 7472function getUrlParameter(sParam) { 7473 var sPageURL = window.location.search.substring(1), 7474 sURLVariables = sPageURL.split('&'), 7475 sParameterName, 7476 i; 7477 7478 for (i = 0; i < sURLVariables.length; i++) { 7479 sParameterName = sURLVariables[i].split('='); 7480 7481 if (sParameterName[0] === sParam) { 7482 return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 7483 } 7484 } 7485 return false; 7486}; 7487function inArray(needle, haystack) { 7488 var length = haystack.length; 7489 for(var i = 0; i < length; i++) { 7490 if(haystack[i] == needle) return true; 7491 } 7492 return false; 7493} 7494 7495function getCookieYes(key) { 7496 const cookiesObj = document.cookie 7497 .split(";") 7498 .reduce((ac, cv) => { 7499 const [k, v] = cv.split("="); 7500 if (k && v) ac[k.trim()] = v; 7501 return ac; 7502 }, {}); 7503 const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"]; 7504 if (!consentCookie) return undefined; 7505 const { [key]: value } = consentCookie 7506 .split(",") 7507 .reduce((obj, pair) => { 7508 const [k, v] = pair.split(":"); 7509 if (k && v) obj[k] = v; 7510 return obj; 7511 }, {}); 7512 return value; 7513} 7514 7515function getRootDomain(useSubdomain = false) { 7516 const hostname = window.location.hostname; // Get the current hostname 7517 // Check if tldjs is defined before using it 7518 if (typeof tldjs === "undefined") { 7519 console.warn("tldjs is not defined"); 7520 return hostname; // Return hostname as a fallback 7521 } 7522 7523 const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain 7524 7525 // Return the root domain with or without a leading dot based on useSubdomain 7526 return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname; 7527}
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.