1(function($){ 2 'use strict'; 3 4 jQuery(document).ready(function(){ 5 6 var timer; 7 var timePeriod = public_data.hours; //Time period in hours 8 var mobileExitIntentEnabled = public_data.mobile_exit_intent_enabled; 9 10 function showExitIntentForm(event){ 11 var currentTime = new Date().getTime(); 12 var last_time_displayed = localStorage.getItem('cartbounty_pro_ei_last_time'); 13 var last_time_moved_back = localStorage.getItem('cartbounty_pro_last_time_moved_back'); 14 var productCount = public_data.product_count; //Products in the shopping cart 15 16 if( event == 'cartbounty_pro_scrolling_up' || event == 'cartbounty_pro_going_back' ){ //In case if user is scrolling up or using back button 17 if(productCount == 0){ 18 return; 19 } 20 else if(last_time_displayed == null || timePeriod == 0) { //If time period has passed or Exit Intent test mode is enabled 21 $('#cartbounty-pro-exit-intent-form').addClass('cartbounty-pro-visible'); //Display form 22 $('#cartbounty-pro-exit-intent-form-backdrop').css('opacity', '').addClass('cartbounty-pro-visible'); //Show backdrop 23 if(timePeriod != 0){ 24 localStorage.setItem('cartbounty_pro_ei_last_time', currentTime); 25 } 26 }else{ 27 if(currentTime - last_time_displayed > timePeriod * 60 * 60 * 1000){ // If the time has expired, clear the cookie 28 localStorage.removeItem('cartbounty_pro_ei_last_time'); 29 } 30 } 31 } 32 33 else if ( event.clientY <= 0 && event.target.tagName.toLowerCase() != 'select' && event.target.tagName.toLowerCase() != 'option' && event.target.tagName.toLowerCase() != 'input') { //Checking if mouse Y poosition goes beyond the top screen and that we haven't clicked on dropdown or autocomplete input field 34 if(productCount == 0){ 35 return; 36 } 37 else if(last_time_displayed == null || timePeriod == 0) { //If time period has passed or Exit Intent test mode is enabled 38 $('#cartbounty-pro-exit-intent-form').addClass('cartbounty-pro-visible'); //Display form 39 $('#cartbounty-pro-exit-intent-form-backdrop').css('opacity', '').addClass('cartbounty-pro-visible'); //Show backdrop 40 if(timePeriod != 0){ 41 localStorage.setItem('cartbounty_pro_ei_last_time', currentTime); 42 } 43 }else{ 44 if(currentTime - last_time_displayed > timePeriod * 60 * 60 * 1000){ // If the time has expired, clear the cookie 45 localStorage.removeItem('cartbounty_pro_ei_last_time'); 46 } 47 } 48 } 49 } 50 51 function getExitIntentEmail() { //Reading email entered in exit intent 52 var cartbounty_pro_email = jQuery('#cartbounty-pro-exit-intent-email').val(); 53 var atposition = cartbounty_pro_email.indexOf('@'); 54 var dotposition = cartbounty_pro_email.lastIndexOf('.'); 55 56 clearTimeout(timer); 57 58 if (!(atposition < 1 || dotposition < atposition + 2 || dotposition + 2 >= cartbounty_pro_email.length)){ //Checking if the email field is valid 59 var data = { 60 action: "cartbounty_pro_save", 61 cartbounty_pro_email: cartbounty_pro_email 62 } 63 64 timer = setTimeout(function(){ 65 if(!public_data.is_user_logged_in && public_data.recaptcha_enabled){ //If the user is not logged in and reCAPTCHA has been enabled 66 grecaptcha.ready(function() { //If reCAPTCHA is loaded and ready 67 grecaptcha.execute(public_data.recaptcha_site_key, {action: 'cartbounty_pro_abandoned_cart_exit_intent'}).then(function(token) { 68 data['cartbounty_pro_recaptcha_token'] = token; //Adding additional token element to the object 69 jQuery.post(public_data.ajaxurl, data, //Ajaxurl coming from localized script and contains the link to wp-admin/admin-ajax.php file that handles AJAX requests on Wordpress 70 function(response) { 71 //console.log(response); 72 }); 73 }); 74 }); 75 76 }else{ //If the user is logged in or if the reCAPTCHA is disabled, not sending data to reCAPTCHA 77 jQuery.post(public_data.ajaxurl, data, //Ajaxurl coming from localized script and contains the link to wp-admin/admin-ajax.php file that handles AJAX requests on Wordpress 78 function(response) { 79 //console.log(response); 80 }); 81 } 82 }, 800); 83 }else{ 84 //console.log('Not a valid e-mail or phone address'); 85 } 86 } 87
88 function insertExitIntentForm(){//Adding Exit Intent form in case if Ajax Add To Cart button pressed 89 var data = { 90 action: "insert_exit_intent", 91 cartbounty_pro_insert: true 92 } 93 94 if($('#cartbounty-pro-exit-intent-form').length <= 0){ //If Exit intent HTML does not exist on page 95 jQuery.post(public_data.ajaxurl, data, //Ajaxurl coming from localized script and contains the link to wp-admin/admin-ajax.php file that handles AJAX requests on Wordpress 96 function(response){ //Response consists of HTML 97 var output = response; 98 $('body').append(output); //Adding Exit Intent form to the footer 99 //Binding these functions once again since HTML added by Ajax is new 100 jQuery('#cartbounty-pro-exit-intent-email').on('keyup keypress change', getExitIntentEmail ); //All action happens on or after changing Email field. Data saved to Database only after Email fields have been entered. 101 jQuery('#cartbounty-pro-exit-intent-close, #cartbounty-pro-exit-intent-form-backdrop').on('click', closeExitIntentForm ); //Close Exit intent window 102 }); 103 } 104 105 public_data.product_count = parseInt(public_data.product_count) + 1; //Updating product count in cart data variable once Add to Cart button is pressed 106 } 107 108 function removeExitIntentFormIfEmptyCart(){//Removing Exit Intent form in case if cart emptied using Ajax 109 var data = { 110 action: "remove_exit_intent", 111 cartbounty_pro_remove: true 112 } 113 if($('#cartbounty-pro-exit-intent-form').length > 0){ //If Exit intent HTML exists on page 114 jQuery.post(public_data.ajaxurl, data, //Ajaxurl coming from localized script and contains the link to wp-admin/admin-ajax.php file that handles AJAX requests on Wordpress 115 function(response){ 116 if(response.data == 'true'){ //If the cart is empty - removing exit intent HTML 117 $('#cartbounty-pro-exit-intent-form').remove(); 118 $('#cartbounty-pro-exit-intent-form-backdrop').remove(); 119 } 120 }); 121 } 122 } 123 124 function closeExitIntentForm(){ //Close exit intent window 125 $('#cartbounty-pro-exit-intent-form').removeClass('cartbounty-pro-visible'); //Hide form 126 $('#cartbounty-pro-exit-intent-form-backdrop').removeClass('cartbounty-pro-visible'); //Hide backdrop 127 } 128 129 function checkIfTouchEnabled(event){ //Checking if the device is a touch enabled device 130 if(mobileExitIntentEnabled){ //If Mobile Exit Intent is enabled 131 if( event.type == 'touchstart'){ 132 localStorage.setItem('cartbounty_pro_touch_device', true); 133 jQuery(document).off('touchstart', checkIfTouchEnabled ); //Removing checking if we are on touch device in case we find it out 134 } 135 } 136 } 137 138 function checkScrollDirection(){ //Checking scroll direction and speed to see if we must display Exit Intent on Mobile 139 if(mobileExitIntentEnabled){ //If Mobile Exit Intent is enabled 140 var cartbounty_pro_touch_device = localStorage.getItem('cartbounty_pro_touch_device'); 141 if( cartbounty_pro_touch_device ){ //Going further only in case we are on a touch enabled device 142 if(cartbounty_pro_scrollSpeed() < -120){ //In case if the user scrolls up with a speed of 150 143 showExitIntentForm('cartbounty_pro_scrolling_up'); 144 } 145 } 146 } 147 } 148 149 var cartbounty_pro_scrollSpeed = (function(){ //Function that checks the speed of scrolling 150 if(mobileExitIntentEnabled){ //If Mobile Exit Intent is enabled 151 var last_position, new_position, timer, delta, delay = 50;// in 'ms' (higher means lower fidelity ) 152 function clear() { 153 last_position = null; 154 delta = 0; 155 } 156 157 clear(); 158 return function(){ 159 new_position = window.scrollY; 160 if ( last_position != null ){ 161 delta = new_position - last_position; 162 } 163 last_position = new_position; 164 clearTimeout(timer); 165 timer = setTimeout(clear, delay); 166 return delta; 167 }; 168 } 169 })(); 170 171 function buildExitIntentHistoryLinks(action){ //Function that builds alternative history 172 var cartbounty_pro_history_links = JSON.parse(localStorage.getItem('cartbounty_pro_history_links') || '[]'); 173 if(action == 'remove'){ //If we have a true value, then we are removing the link from history. Used in case if the user clicks the back button 174 cartbounty_pro_history_links.pop(); 175 }else{ //Modifying history. Adding history link to a stack of history 176 var link = { 177 url: location.href 178 }; 179 cartbounty_pro_history_links.push(link); 180 } 181 localStorage.setItem('cartbounty_pro_history_links', JSON.stringify(cartbounty_pro_history_links)); //Saving history in session 182 } 183 184 function handleExitIntentBackButton() { //Function handles the Exit Intent in case user uses back button on mobile 185 var cartbounty_pro_history_links = JSON.parse(localStorage.getItem('cartbounty_pro_history_links') || '[]'); 186 var last_history_link_id = cartbounty_pro_history_links.length - 1; 187 var last_history_link_url = cartbounty_pro_history_links[last_history_link_id].url; 188 var cartbounty_pro_show_exit_intent_on_back_button = localStorage.getItem('cartbounty_pro_show_exit_intent_on_back_button'); 189 if(timePeriod == 0){ //If Exit Intent test mode is enabled 190 cartbounty_pro_show_exit_intent_on_back_button = null; 191 } 192 var count = 0; 193 194 addEventListener('popstate', function(event){ 195 //Calculating how many pages should we be going back in history. 196 while( cartbounty_pro_history_links.length > 0 && location.href == last_history_link_url && count < 10 ){ //In case if the history is too long, we are using count to exit the loop. If the current page link is equal to previous, we are looking for a new link that would be different from the current one and also looping until we have at least one link in the history 197 last_history_link_url = cartbounty_pro_history_links.pop().url; //Removing last link from history 198 count++; 199 buildExitIntentHistoryLinks('remove'); //Removing the last element from the history 200 } 201 202 if( cartbounty_pro_show_exit_intent_on_back_button == null || cartbounty_pro_show_exit_intent_on_back_button == false ){ //In case if the user goes back for the first time, we are displaying the Exit Intent window 203 localStorage.setItem('cartbounty_pro_show_exit_intent_on_back_button', true); 204 showExitIntentForm('cartbounty_pro_going_back'); 205 }else{ //Going back in history 206 history.go(-count); 207 } 208 }); 209 } 210 211 function startExitIntentBack(){ //Fires functions once the document has been loaded and is ready 212 if(mobileExitIntentEnabled){ //If Mobile Exit Intent is enabled 213 var cartbounty_pro_touch_device = localStorage.getItem('cartbounty_pro_touch_device'); 214 if( cartbounty_pro_touch_device ){ //Runing functions only on touch enabled devices 215 history.pushState(null, null, location.href); //Adding current url to history 216 buildExitIntentHistoryLinks('add'); //Adding current url to history 217 handleExitIntentBackButton(); 218 } 219 } 220 } 221 startExitIntentBack(); 222 223 jQuery(document).on('mouseleave', showExitIntentForm); //Displaying Exit intent if the mouse leaves the window 224 jQuery('#cartbounty-pro-exit-intent-email').on('keyup keypress change', getExitIntentEmail ); //All action happens on or after changing Email field. Data saved to Database only after Email fields have been entered. 225 jQuery('#cartbounty-pro-exit-intent-close, #cartbounty-pro-exit-intent-form-backdrop').on('click', closeExitIntentForm ); //Close Exit intent window 226 jQuery(document).on('added_to_cart', insertExitIntentForm ); //Calling Exit Intent form function output if Add to Cart button is pressed 227 jQuery(document).on('removed_from_cart', removeExitIntentFormIfEmptyCart ); //Firing the function if item is removed from cart via Ajax 228 jQuery(document).on('touchstart', checkIfTouchEnabled ); 229 jQuery(document).on('scroll', checkScrollDirection ); //Binding function to scroll event 230 }); 231 232})(jQuery);
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.