1/** 2 * @namespace MintAbandonedCart 3 */ 4 5/** 6 * @typedef {Object} FormData 7 * @property {string} email - The email address. 8 * @property {Object} checkout_fields_data - The data of checkout fields. 9 * @property {string} wp_nonce - The WordPress nonce. 10 * @property {string} action - The action to perform. 11 */ 12 13/** 14 * @typedef {Object} Response 15 * @property {Function} json - A function to parse the response as JSON. 16 */ 17 18/** 19 * @callback FetchCallback 20 * @param {Response} res - The fetch response object. 21 */ 22 23/** 24 * @typedef {Object} MintProFrontendVars 25 * @property {Object} abandoned_setting - The abandoned cart settings. 26 * @property {boolean} enable - Indicates if abandoned cart feature is enabled. 27 * @property {string} nonce - The WordPress nonce. 28 */ 29 30/** 31 * Represents the MintAbandonedCart module. 32 * @type {Object} 33 */ 34var MintAbandonedCart; 35 36(function ($) { 37 "use strict"; 38 /** 39 * Serialize and encode the form object. 40 * @returns {string} The serialized and encoded form data. 41 */ 42 $.fn.mint_serializeAndEncode = function () { 43 return $.map(this.serializeArray(), function (val) { 44 let field = $("input[name='" + val.name + "']"); 45 if (field.attr('type') == 'checkbox') { 46 if (field.prop("checked")) { 47 return [val.name, encodeURIComponent('1')].join('='); 48 } else { 49 return [val.name, encodeURIComponent('0')].join('='); 50 } 51 } else { 52 return [val.name, encodeURIComponent(val.value)].join('='); 53 } 54 }).join('&'); 55 }; 56 57 /** 58 * Initializes the MintAbandonedCart module. 59 */ 60 MintAbandonedCart = { 61 checkout_form: $('form.checkout'), 62 checkout_fields_data: {}, 63 checkout_fields: [], 64 updateCheckout: 0, 65 66 /** 67 * Initializes the MintAbandonedCart module. 68 */ 69 init: function () { 70 this.checkout_fields = [ 71 'billing_first_name', 72 'billing_last_name', 73 'billing_company', 74 'billing_phone', 75 'billing_country', 76 'billing_address_1', 77 'billing_address_2', 78 'billing_city', 79 'billing_state', 80 'billing_postcode', 81 'shipping_first_name', 82 'shipping_last_name', 83 'shipping_company', 84 'shipping_country', 85 'shipping_address_1', 86 'shipping_address_2', 87 'shipping_city', 88 'shipping_state', 89 'shipping_postcode', 90 'shipping_phone', 91 ]; 92 93 $.each(MintAbandonedCart.checkout_fields, function (i, field_name) { 94 MintAbandonedCart.checkout_fields_data[field_name] = ''; 95 }); 96 97 this.add_gdpr_message(); 98 }, 99 100 /** 101 * Captures the email when focus is lost on the billing email field. 102 */ 103 mint_capture_email: function () { 104 $(document).on('focusout', '#billing_email, #email', function () { 105 MintAbandonedCart.mint_get_checkout_data(); 106 }); 107 108 var billing_email = jQuery('#billing_email').val(); 109 110 if( !billing_email ){ 111 billing_email = jQuery('#email').val(); 112 } 113 114 if (billing_email !== '' && MintAbandonedCart.mint_isValidEmailAddress(billing_email)) { 115 MintAbandonedCart.mint_capture_data_on_page_load(); 116 MintAbandonedCart.mint_process_email(billing_email); 117 } 118 }, 119 120 /** 121 * Gets the checkout data when the billing email field is modified. 122 */ 123 mint_get_checkout_data: function () { 124 var email = $('#billing_email').val(); 125 126 if (!email) { 127 email = $('#email').val(); 128 } 129 130 if (email !== '' && MintAbandonedCart.mint_isValidEmailAddress(email)) { 131 MintAbandonedCart.mint_process_email(email); 132 } 133 }, 134 135 /** 136 * Captures the checkout data on page load. 137 */
138 mint_capture_data_on_page_load: function () { 139 $.each(MintAbandonedCart.checkout_fields, function (i, field_name) { 140 var $this = $('#' + field_name); 141 MintAbandonedCart.checkout_fields_data[field_name] = $this.val(); 142 }); 143 }, 144 145 /** 146 * Captures the checkout field data when a change event occurs. 147 */ 148 mint_captureCheckoutField: function () { 149 if (MintAbandonedCart.updateCheckout === 0 && !window.MintProFrontendVars?.is_checkout_block) { 150 return; 151 } 152 153 var field_name = $(this).attr('name'); 154 155 if(!field_name){ 156 field_name = $(this).attr('id'); 157 var checkout_formdata = MintAbandonedCart.get_form_data(); 158 MintAbandonedCart.checkout_fields_data = checkout_formdata; 159 return; 160 } 161 /** for checking checkbox fields **/ 162 if ($(this).attr('type') == 'checkbox') { 163 if ($(this).prop('checked')) { 164 $(this).val(1); 165 } else { 166 $(this).val(0); 167 } 168 } 169 if (!field_name || MintAbandonedCart.checkout_fields.indexOf(field_name) === -1) { 170 return; 171 } 172 173 if (!$(this).val() || MintAbandonedCart.checkout_fields_data[field_name] === $(this).val()) { 174 return; 175 } 176 var checkout_formdata = MintAbandonedCart.checkout_form.mint_serializeAndEncode(); 177 checkout_formdata = mint_deserialize_obj(checkout_formdata); 178 MintAbandonedCart.checkout_fields_data = checkout_formdata; 179 }, 180 181 /** 182 * Processes the email and updates the checkout data. 183 * @param {string} email - The email address. 184 */ 185 mint_process_email: function (email) { 186 if ('undefined' === typeof email || !window.MintProFrontendVars?.abandoned_setting.enable || (0 === MintAbandonedCart.updateCheckout && !window.MintProFrontendVars?.is_checkout_block) || '' === email ) { 187 return; 188 } 189 190 var data = new FormData(); 191 data.append("email", email); 192 data.append("checkout_fields_data", JSON.stringify(MintAbandonedCart.checkout_fields_data)); 193 data.append("wp_nonce", window.MintProFrontendVars?.nonce); 194 fetch("/wp-json/mail-mint/v1/abandoned-cart/update-checkout", { 195 method: "POST", 196 headers: { 197 'Access-Control-Allow-Origin': '*', 198 'X-WP-Nonce': window.MintProFrontendVars?.nonce 199 }, 200 body: data 201 }) 202 .then(function (res) { 203 return res.json(); 204 }) 205 .then(function (response) { 206 // Handle the response if needed 207 }); 208 }, 209 210 /** 211 * Checks if the given email address is valid. 212 * @param {string} emailAddress - The email address to validate. 213 * @returns {boolean} True if the email address is valid, false otherwise. 214 * @since 1.5.0 215 */ 216 mint_isValidEmailAddress: function (emailAddress) { 217 var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i); 218 219 return pattern.test(emailAddress); 220 }, 221 222 /** 223 * Initializes the abandoned cart functionality. 224 */ 225 abandoned_cart: function () { 226 if (window.MintProFrontendVars?.abandoned_setting.enable) { 227 MintAbandonedCart.mint_capture_email(); 228 } 229 }, 230 231 get_form_data: function(){ 232 const data = {}; 233 MintAbandonedCart.checkout_form.find('input, select, textarea').each(function() { 234 const id = $(this).attr('id'); // Use 'id' as the key 235 if (id) { // Make sure the field has an 'id' 236 if ($(this).is(':checkbox')) { 237 data[id] = $(this).is(':checked'); // For checkboxes, store whether they are checked 238 } else if ($(this).is(':radio')) { 239 if ($(this).is(':checked')) { 240 data[id] = $(this).val(); // For radio buttons, store the value of the selected one 241 } 242 } else { 243 data[id] = $(this).val(); // For other inputs, store the value 244 } 245 } 246 }); 247 return data; 248 }, 249 250 add_gdpr_message: function () { 251 if(window.MintProFrontendVars?.abandoned_setting.enable && 'require' === window.MintProFrontendVars?.abandoned_setting.gdpr_consent){ 252 if (!$('.wc-block-components-address-form__email').length) { 253 setTimeout(() => { 254 this.add_gdpr_message(); 255 }, 2000); 256 return; 257 } 258 if ($('.mint-form-control-wrapper').length) { 259 return; 260 } 261 var mint_no_thanks = window.MintProFrontendVars?.abandoned_setting.consent_text 262 var mint_no_thanks_text = 'Your email and cart are saved so we can send you email reminders about this order' 263 var mint_no_thanks_link_text = 'No Thanks' 264 var mint_no_thanks_array = mint_no_thanks.split('{{') 265 if( 2 === mint_no_thanks_array. length ){ 266 mint_no_thanks_text = mint_no_thanks_array[0] 267 mint_no_thanks_link_text = mint_no_thanks_array[1]; 268 mint_no_thanks_link_text= mint_no_thanks_link_text.match(/label="([^"]+)"/)[1]; 269 } 270 const text_link = "<a class='mint_email_consent_no_thanks'>
270" + mint_no_thanks_link_text + "</a>"; 271 var mint_email_gdpr_consent_message = '<span class="mint-gdpr-consent-text">' + mint_no_thanks_text + text_link + '</span>'; 272 const emailConsentHtml = '<input type="hidden" id="mint_email_gdpr_consent" value="1" />'; 273 mint_email_gdpr_consent_message += emailConsentHtml; 274 $('.wc-block-components-address-form__email').after('<span class="form-row form-row-wide mint-form-control-wrapper mint-col-full">' + mint_email_gdpr_consent_message + '</span>'); 275 $(".mint_email_consent_no_thanks").on('click',function (){ 276 277 var email = $('#billing_email').val(); 278 if (!email) { 279 email = $('#email').val(); 280 } 281 282 var data = new FormData(); 283 var that = $(this) 284 data.append("email", email); 285 data.append("wp_nonce", window.MintProFrontendVars?.nonce); 286 fetch("/wp-json/mail-mint/v1/abandoned-cart/skip-track", { 287 method: "POST", 288 headers: { 289 'Access-Control-Allow-Origin': '*', 290 'X-WP-Nonce': window.MintProFrontendVars?.nonce 291 }, 292 body: data 293 }) 294 .then(function (res) { 295 return res.json(); 296 }) 297 .then(function (response) { 298 $('#mint_email_gdpr_consent').val('0'); 299 that.parent().fadeOut("slow"); 300 }); 301 302 }) 303 } 304 }, 305 }; 306 307 /** 308 * Abandoned cart JS Function Initiate here 309 */ 310 MintAbandonedCart.abandoned_cart = function () { 311 if (window.MintProFrontendVars?.abandoned_setting.enable) { 312 MintAbandonedCart.mint_capture_email(); 313 } 314 }; 315 316 /* Initialize */ 317 MintAbandonedCart.init(); 318 319 /** 320 * Event handlers 321 */ 322 $(window).on('load', function () { 323 MintAbandonedCart.abandoned_cart(); 324 if(!MintAbandonedCart.checkout_form.length){ 325 setTimeout(()=>{ 326 MintAbandonedCart.checkout_form = $('form.wc-block-components-form'); 327 if(MintAbandonedCart.checkout_form.length > 0){ 328 MintAbandonedCart.checkout_form.on('change', 'input', MintAbandonedCart.mint_captureCheckoutField); 329 MintAbandonedCart.checkout_form.on('change', 'select', MintAbandonedCart.mint_captureCheckoutField); 330 MintAbandonedCart.checkout_form.on('click change', '.input-checkbox', MintAbandonedCart.mint_captureCheckoutField); 331 MintAbandonedCart.checkout_form.on('blur change', '.input-text', MintAbandonedCart.mint_captureCheckoutField); 332 MintAbandonedCart.checkout_form.on('focusout', '.input-text', MintAbandonedCart.mint_captureCheckoutField); 333 $(document).on('blur change', 'input', MintAbandonedCart.mint_get_checkout_data); 334 } 335 }, 100) 336 } 337 // Detect change and save data in database 338 MintAbandonedCart.checkout_form.on('change', 'select', MintAbandonedCart.mint_captureCheckoutField); 339 MintAbandonedCart.checkout_form.on('click change', '.input-checkbox', MintAbandonedCart.mint_captureCheckoutField); 340 MintAbandonedCart.checkout_form.on('blur change', '.input-text', MintAbandonedCart.mint_captureCheckoutField); 341 MintAbandonedCart.checkout_form.on('focusout', '.input-text', MintAbandonedCart.mint_captureCheckoutField); 342 $(document).on('blur change', '#billing_email, #email, .input-text,.input-checkbox', MintAbandonedCart.mint_get_checkout_data); 343 }); 344 345 $(document).on('updated_checkout', function () { 346 // Update Checkout is triggered 347 MintAbandonedCart.updateCheckout = 1; 348 MintAbandonedCart.mint_captureCheckoutField(); 349 var email = $('#billing_email').val(); 350 if( !email ){ 351 email = $('#email').val(); 352 } 353 if ('' !== email ) { 354 MintAbandonedCart.mint_process_email(email); 355 } 356 }); 357 358 if( window.MintProFrontendVars?.abandoned_setting.enable && 'require' === window.MintProFrontendVars?.abandoned_setting.gdpr_consent){ 359 var mint_no_thanks = window.MintProFrontendVars?.abandoned_setting.consent_text 360 var mint_no_thanks_text = 'Your email and cart are saved so we can send you email reminders about this order' 361 var mint_no_thanks_link_text = 'No Thanks' 362 var mint_no_thanks_array = mint_no_thanks.split('{{') 363 if( 2 === mint_no_thanks_array. length ){ 364 mint_no_thanks_text = mint_no_thanks_array[0] 365 mint_no_thanks_link_text = mint_no_thanks_array[1]; 366 mint_no_thanks_link_text= mint_no_thanks_link_text.match(/label="([^"]+)"/)[1]; 367 } 368 const text_link = "<a class='mint_email_consent_no_thanks' style='text-decoration:underline;cursor: pointer;'>" +mint_no_thanks_link_text + "</a>"; 369 var mint_email_gdpr_consent_message = '<span>' + mint_no_thanks_text + text_link +'</span>'; 370 const emailConsentHtml = '<input type="hidden" id="mint_email_gdpr_consent" value="1" />'; 371 mint_email_gdpr_consent_message += emailConsentHtml; 372 373 $('#billing_email_field .woocommerce-input-wrapper #billing_email').after('<span class="form-row form-row-wide mint-form-control-wrapper mint-col-full">' + mint_email_gdpr_consent_message + '</span>'); 374 $(".mint_email_consent_no_thanks").on('click',function (){ 375 var email = $('#billing_email').val(); 376 if (!email) { 377 email = $('#email').val(); 378 } 379 380 var data = new FormData(); 381 var that = $(this) 382 data.append("email", email); 383 data.append("wp_nonce", window.MintProFrontendVars?.nonce); 384 fetch("/wp-json/mail-mint/v1/abandoned-cart/skip-track", { 385 method: "POST", 386 headers: { 387 'Access-Control-Allow-Origin': '*', 388 'X-WP-Nonce': window.MintProFrontendVars?.nonce 389 }, 390 body: data 391 }) 392 .then(function (res) { 393 return res.json(); 394 }) 395 .then(function (response) { 396 $('#mint_email_gdpr_consent').val('0'); 397 that.parent().fadeOut("slow"); 398 }); 399 400 }) 401 402 } 403 404})(jQuery); 405 406/** 407 * Deserializes the query string into an object. 408 * @param {string}
408 query - The query string to deserialize. 409 * @returns {object} The deserialized object. 410 */ 411function mint_deserialize_obj(query) { 412 var setValue = function (root, path, value) { 413 if (path.length > 1) { 414 var dir = path.shift(); 415 if (typeof root[dir] === 'undefined') { 416 root[dir] = path[0] === '' ? [] : {}; 417 } 418 419 arguments.callee(root[dir], path, value); 420 } else { 421 if (root instanceof Array) { 422 root.push(value); 423 } else { 424 root[path] = value; 425 } 426 } 427 }; 428 429 var nvp = query.replace('?', '').split('&'); 430 var data = {}; 431 432 for (var i = 0; i < nvp.length; i++) { 433 var pair = nvp[i].split('='); 434 var name = decodeURIComponent(pair[0]); 435 var value = decodeURIComponent(pair[1]); 436 437 var path = name.match(/(^[^\[]+)(\[.*\]$)?/); 438 var first = path[1]; 439 if (path[2]) { 440 // case of 'array[level1]' || 'array[level1][level2]' 441 path = path[2].match(/(?=\[(.*)\]$)/)[1].split(']['); 442 } else { 443 // case of 'name' 444 path = []; 445 } 446 path.unshift(first); 447 448 setValue(data, path, value); 449 } 450 451 return data; 452}
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.