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