PageSourceSearch

https://dohost.us/wp-content/plugins/mail-mint/assets/frontend/js/frontend.js?ver=1.21.0

js dohost.us collected 2026-10-08 10:37:40 UTC 22,446 bytes, 556 lines download raw bytes

1jQuery(document).ready(function ($) {
2    /**
3     * Inline Validation System
4     */
5    function initInlineValidation() {
6        // Add validation error container after each required field
7        $('.mrm-form-wrapper-inner form').each(function() {
8            $(this).find('[required]').each(function() {
9                var $field = $(this);
10                var $formGroup = $field.closest('.mrm-form-group, .mrm-input-group');
11                
12                // Add error message container if not exists
13                if ($formGroup.length && !$formGroup.find('.mrm-validation-error').length) {
14                    $formGroup.append('<span class="mrm-validation-error">This field is required</span>');
15                }
16                
17                // Override browser default validation tooltip
18                $field.on('invalid', function(e) {
19                    e.preventDefault();
20                    showFieldError($field);
21                });
22                
23                // Clear error on input
24                $field.on('input change', function() {
25                    clearFieldError($field);
26                });
27            });
28        });
29    }
30
31    function showFieldError($field) {
32        var $formGroup = $field.closest('.mrm-form-group, .mrm-input-group');
33        var errorMessage = getValidationMessage($field);
34        
35        $formGroup.addClass('has-error');
36        $formGroup.find('.mrm-validation-error').text(errorMessage);
37    }
38
39    function clearFieldError($field) {
40        var $formGroup = $field.closest('.mrm-form-group, .mrm-input-group');
41        $formGroup.removeClass('has-error');
42    }
43
44    function getValidationMessage($field) {
45        var field = $field[0];
46        
47        if (field.validity.valueMissing) {
48            return 'This field is required';
49        }
50        if (field.validity.typeMismatch) {
51            if (field.type === 'email') {
52                return 'Please enter a valid email address';
53            }
54            return 'Please enter a valid value';
55        }
56        if (field.validity.patternMismatch) {
57            return 'Please match the requested format';
58        }
59        
60        return 'Please fill out this field correctly';
61    }
62
63    function validateForm($form) {
64        var isValid = true;
65        
66        $form.find('[required]').each(function() {
67            var $field = $(this);
68            var field = $field[0];
69            
70            if (!field.checkValidity()) {
71                showFieldError($field);
72                isValid = false;
73            } else {
74                clearFieldError($field);
75            }
76        });
77        
78        // Focus first invalid field
79        if (!isValid) {
80            $form.find('.has-error').first().find('input, select, textarea').focus();
81        }
82        
83        return isValid;
84    }
85
86    // Initialize inline validation
87    initInlineValidation();
88
89    /**
90     * Shortcode form submission ajax
91     */
92
93    $(".mrm-form-wrapper-inner form").on("submit",function (e){
94        e.preventDefault();
95        
96        // Run inline validation first
97        if (!validateForm($(this))) {
98            return false;
99        }
100        
101        $(this).find(".response").html("");
102        $(this).find(".mrm-submit-button").addClass("show-loader");
103        $(this).find(".mrm-submit-button").attr('disabled','disabled');
104        let that = this;
105        var data = new FormData();
106        data.append( "post_data", $(that).serialize() );
107        data.append( "wp_nonce", window.MRM_Frontend_Vars.nonce ); // This nonce is created in the following file: /app/Internal/Frontend/FrontendAssets.php
108        data.append( "action", "mrm_submit_form");
109        // Capture source URL and UTM parameters for submission tracking.
110        data.append( "source_url", window.location.href );
111        var _mintUrlParams = new URLSearchParams( window.location.search );
112        [ "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content" ].forEach( function( key ) {
113            if ( _mintUrlParams.has( key ) ) {
114                data.append( key, _mintUrlParams.get( key ) );
115            }
116        } );
117        fetch(window.MRM_Frontend_Vars.rest_api_url+"mint-mail/v1/mint-form-submit",
118            {
119                method: "POST",
120                body: data
121            })
122            .then(function(res){ return res.json(); })
123            .then(function(response){
124                $(that).find(".mrm-submit-button").removeClass("show-loader");
125                $(that).find(".mrm-submit-button").removeAttr('disabled');
126                if (response.status === "success") {
127                    $(".response").addClass("mintmrm-success");
128                    $(".response").removeClass("mintmrm-error");
129                    $(that).find(".mrm-submit-button").removeClass("show-loader");
130                    if (response.confirmation_type === "same_page") {
131                        if (response.after_form_submission === "hide_form") {
132                            $(".mrm-form-wrapper form").hide();
133                            $(".mrm-form-wrapper").hide();
134                        } else if (
135                            response.after_form_submission === "reset_form"
136                        ) {
137                            $("#mrm-form")[0].reset();
138                        }
139                    }
140                    if (response.confirmation_type === "to_a_page") {
141                        if (response.redirect_page) {
142                            setTimeout(function () {
143                                window.location.href = response.redirect_page;
144                            }, 2000);
145                        } else {
146                            setTimeout(function () {
147                                $(that).find(".response").html(
148                                    "Redirect URL not found"
149                                );
150                            }, 2000);
151                        }
152                    }
153                    if (response.confirmation_type === "to_a_custom_url") {
154                        if (response.custom_url !== "") {
155                            setTimeout(function () {
156                                window.location.href = response.custom_url;
157                            }, 1000);
158                        }
159                    }
160                    if (response.confirmation_type === "download") {
161                        fetch(response.file_url)
162                            .then(response => response.blob())
163                            .then(blob => {
164                                const url = window.URL.createObjectURL(blob);
165                                const link = document.createElement('a');
166                                link.href = url;
167                                link.download = response.file_name || 'download';
168                                link.style.display = 'none';
169                                
170                                document.body.appendChild(link);
171                                link.click();
172                                document.body.removeChild(link);
173                                
174                                // Clean up the object URL
175                                window.URL.revokeObjectURL(url);
176                            })
177                            .catch(error => {
178                                console.error('Download failed:', error);
179                                // Fallback to direct link
180                                window.open(response.file_url, '_blank');
181                            });
182                            
183                        if (response.after_form_submission === "hide_form") {
184                            $(".mrm-form-wrapper form").hide();
185                            $(".mrm-form-wrapper").hide();
186                        } else if (response.after_form_submission === "reset_form") {
187                            $("#mrm-form")[0].reset();
188                        }
189                    }
190                    $(that).parent().find(".response").html(response.message);
191                    $(that).find(".response").html(response.message);
192                } else if (response.status == "failed") {
193                    $(that).find(".response").addClass("mintmrm-error");
194                    $(that).find(".response").removeClass("mintmrm-success");
195                    $(that).find(".response").html(response.message);
196                    $(that).find(".mrm-submit-button").removeAttr('disabled');
197                }
198
199            })
200    })
201
202    function modifyQueryString(input) {
203        // Split the input string into key-value pairs
204        const pairs = input.split('&');
205        const result = [];
206        const mrmList = [];
207    
208        pairs.forEach(pair => {
209            const [key, value] = pair.split('=');
210    
211            // Keep the key-value pairs that are not list items
212            if (!/^\d+$/.test(key)) {
213                result.push(`${key}=${value}`);
214            } else {
215                // Collect list item keys
216                mrmList.push(key);
217            }
218        });
219    
220        // Append the mrm_list items in the desired format
221        mrmList.forEach(item => {
222            result.push(`mrm_list%5B%5D=${item}`);
223        });
224    
225        // Join the result array into a string
226        return result.join('&');
227    }
228
229    $("#mrm-preference-form").on("submit", function (e) {
230        e.preventDefault();
231        jQuery(".response").html("");
232        $(".mrm-pref-submit-button").addClass("show-loader");
233        var data = new FormData();
234        var postData = jQuery("#mrm-preference-form").serialize();
235        var modifiedQueryString = modifyQueryString(postData);
236        postData = modifiedQueryString;
237        data.append( "post_data", modifiedQueryString );
238        data.append( "wp_nonce", window.MRM_Frontend_Vars.nonce ); // This nonce is created in the following file: /app/Internal/Frontend/FrontendAssets.php
239        data.append( "action", "mrm_preference_update_by_user");
240        fetch(window.MRM_Frontend_Vars.rest_api_url+"mint-mail/v1/mint-preference-submit",
241            {
242                method: "POST",
243                body: data
244            })
245            .then(function(res){ return res.json(); })
246            .then(function(response){
247                if (response.status == "success") {
248                    $(".mrm-pref-submit-button").removeClass("show-loader");
249                    $("#mrm-preference-form").hide();
250                    $(".response").addClass("mintmrm-success");
251                    $(".response").removeClass("mintmrm-error");
252                    $(".response").html(response.message);
253                } else if (response.status == "failed") {
254                    jQuery(".response").addClass("mintmrm-error");
255                    jQuery(".response").removeClass("mintmrm-success");
256                    jQuery(".response").html(response.message);
257                    $(".mrm-pref-submit-button").removeClass("show-loader");
258                }
259            })
260    });
261
262    /**
263     * Set cokokie
264     * @param name
265     * @param value
266     * @param daysToLive
267     */
268    function setCookie(cName, cValue, expDays) {
269        let date = new Date();
270        date.setTime(date.getTime() + expDays * 24 * 60 * 60 * 1000);
271        const expires = "expires=" + date.toUTCString();
272
273        var value = { show: cValue, expire: date.getTime() };
274
275        document.cookie =
276            cName + "=" + JSON.stringify(value) + "; " + expires + "; path=/";
277    }
278    /**
279     * Form Close button Function
280     */
281
282
283    $(".mrm-form-close").on("click", function () {
284        $(this).parent().parent().hide();
285        var form_id = $(this).attr('form-id')
286        let that = this;
287
288        // For "every_time" frequency, clear session mark so next exit intent can re-trigger
289        var formWrapper = $(this).closest('[data-exit-intent="true"]');
290        if (formWrapper.length && formWrapper.attr('data-exit-intent-frequency') === 'every_time') {
291            var sessionKey = 'exitIntentShownForms';
292            var shownForms = JSON.parse(sessionStorage.getItem(sessionKey) || '{}');
293            delete shownForms[form_id];
294            sessionStorage.setItem(sessionKey, JSON.stringify(shownForms));
295        }
296
297        var data = new FormData();
298        data.append( "form_id", form_id );
299        data.append( "action", "set_mint_mail_cookie_for_form");
300        data.append( "wp_nonce", window.MRM_Frontend_Vars.nonce ); // This nonce is created in the following file: /app/Internal/Frontend/FrontendAssets.php
301
302        fetch(window.MRM_Frontend_Vars.rest_api_url+"mint-mail/v1/mint-form-cookie-submit",
303            {
304                method: "POST",
305                body: data
306            })
307            .then(function(res){ return res.json(); })
308            .then(function(response){
309                if( "success" === response.status){
310                    $(that).parent().parent().hide();
311                }else{
312                    $(that).parent().parent().hide();
313                }
314            })
315    });
316
317    if ($("#mint-google-recaptcha").length > 0) {
318        var recaptch_mint = $('[id="mint-google-recaptcha"]');
319        if(window.MRM_Frontend_Vars.recaptcha_settings.enable &&  window.MRM_Frontend_Vars.recaptcha_settings.api_version === "v2_visible"){
320            recaptch_mint.append(`
vendor: 75 bytes, line 320
320<script src="https://www.google.com/recaptcha/api.js" async defer></script>
320`)
321        }
322        if(window.MRM_Frontend_Vars.recaptcha_settings.enable &&  window.MRM_Frontend_Vars.recaptcha_settings.api_version === "v2_visible"){
323            recaptch_mint.append(`<div class="g-recaptcha" data-sitekey="`+window.MRM_Frontend_Vars.recaptcha_settings.v2_visible.site_key+`"></div>`)
324
325            document.addEventListener("DOMContentLoaded", function() {
326                var site_key = window.MRM_Frontend_Vars.recaptcha_settings.v3_invisible.site_key;
327                grecaptcha.ready(function() {
328                    grecaptcha.execute(site_key, { action: "homepage" }).then(function(token) {
329                        document.getElementById("g-recaptcha-response").value = token;
330                    });
331                });
332            });
333        }
334    }
335
336    $(".mint-form-button").on('click',function (){
337         $(this).parent().parent().find('#mrm-popup').css("display","flex");
338    })
339
340    /**
341     * Exit Intent Detection
342     * Triggers popup when user moves mouse towards the top of the page (exit intent)
343     * Supports frequency: once_per_session, once_per_x_days, every_time
344     */
345    function initExitIntentDetection() {
346        const sessionKey = 'exitIntentShownForms';
347
348        // Initialize sessionStorage
349        if (!sessionStorage.getItem(sessionKey)) {
350            sessionStorage.setItem(sessionKey, JSON.stringify({}));
351        }
352
353        function hasShownInSession(formId) {
354            const shownForms = JSON.parse(sessionStorage.getItem(sessionKey) || '{}');
355            return shownForms[formId] === true;
356        }
357
358        function markAsShownInSession(formId) {
359            const shownForms = JSON.parse(sessionStorage.getItem(sessionKey) || '{}');
360            shownForms[formId] = true;
361            sessionStorage.setItem(sessionKey, JSON.stringify(shownForms));
362        }
363
364        function setFrequencyCookie(formId, days) {
365            var date = new Date();
366            date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
367            document.cookie = 'mrm_exit_intent_' + formId + '=shown; expires=' + date.toUTCString() + '; path=/';
368        }
369
370        function hasFrequencyCookie(formId) {
371            return document.cookie.split('; ').some(function(row) {
372                return row.startsWith('mrm_exit_intent_' + formId + '=');
373            });
374        }
375
376        function canShowForm(formWrapper) {
377            var formId = formWrapper.getAttribute('data-form-id');
378            var frequency = formWrapper.getAttribute('data-exit-intent-frequency') || 'once_per_session';
379
380            if (frequency === 'every_time') {
381                // For every_time, still prevent multiple triggers within same mouse-exit event
382                // but allow re-trigger on next exit intent
383                return true;
384            }
385
386            if (frequency === 'once_per_x_days') {
387                return !hasFrequencyCookie(formId);
388            }
389
390            // Default: once_per_session
391            return !hasShownInSession(formId);
392        }
393
394        function markFormAsShown(formWrapper) {
395            var formId = formWrapper.getAttribute('data-form-id');
396            var frequency = formWrapper.getAttribute('data-exit-intent-frequency') || 'once_per_session';
397            var days = parseInt(formWrapper.getAttribute('data-exit-intent-frequency-days')) || 7;
398
399            // Always mark in session to prevent rapid re-triggers
400            markAsShownInSession(formId);
401
402            if (frequency === 'once_per_x_days') {
403                setFrequencyCookie(formId, days);
404            }
405        }
406
407        function showExitIntentForms() {
408            var exitIntentForms = document.querySelectorAll('[data-exit-intent="true"]');
409
410            exitIntentForms.forEach(function(formWrapper) {
411                var formId = formWrapper.getAttribute('data-form-id');
412                if (!formId) return;
413
414                if (!canShowForm(formWrapper)) return;
415
416                // Check for dismiss cookie
417                var cookieExists = document.cookie.split('; ').some(function(row) {
418                    return row.startsWith('mrm_form_cookie_' + formId + '=');
419                });
420
421                if (!cookieExists) {
422                    formWrapper.classList.remove('mrm-form-disable');
423                    formWrapper.style.display = 'flex';
424                    markFormAsShown(formWrapper);
425                }
426            });
427        }
428
429        // Detect when mouse leaves the window from the top (exit intent)
430        document.addEventListener('mouseleave', function(e) {
431            if (e.clientY > 0) return;
432            showExitIntentForms();
433        });
434
435        // Alternative: Detect cursor position very close to top
436        let lastClientY = null;
437        const exitThreshold = 0;
438
439        document.addEventListener('mousemove', function(e) {
440            const currentY = e.clientY;
441
442            if (currentY > exitThreshold) {
443                lastClientY = currentY;
444                return;
445            }
446
447            if (lastClientY !== null && currentY < lastClientY) {
448                showExitIntentForms();
449            }
450
451            lastClientY = currentY;
452        });
453    }
454
455    // Initialize exit-intent detection when DOM is ready
456    if (document.readyState === 'loading') {
457        document.addEventListener('DOMContentLoaded', initExitIntentDetection);
458    } else {
459        initExitIntentDetection();
460    }
461
462    
463    $('#mrm-unsubscribe-cancel').on('click', function(e) {
464        e.preventDefault();
465        window.close();
466    });
467
468    // Toggle dropdown visibility
469    $('.mintmrm-dropdown-button').on('click', function(e) {
470        e.preventDefault();
471        $(this).toggleClass('show');
472        $('.add-contact.mintmrm-dropdown').toggleClass('show');
473    });
474
475    // Close dropdown when clicking outside
476    $(document).on('click', function(e) {
477        if (!$(e.target).closest('.mintmrm-dropdown-button, .add-contact.mintmrm-dropdown').length) {
478            $('.mintmrm-dropdown-button').removeClass('show');
479            $('.add-contact.mintmrm-dropdown').removeClass('show');
480        }
481    });
482
483    const updateDropdownButton = () => {
484        const $dropdownButton = $('.mintmrm-dropdown-button');
485        const $checkboxes = $('.mintmrm-dropdown-list input[type="checkbox"]').not('#all-items-create');
486        const $checkedCheckboxes = $checkboxes.filter(':checked');
487
488        $dropdownButton.empty();
489        if ($checkedCheckboxes.length > 0) {
490            $checkedCheckboxes.each(function() {
491                const title = $(this).next('label').text();
492                $dropdownButton.append(
493                    `<span class="single-list mintmrm-tag-list">${title}
494                        <span class="close-list" title="Delete">&#10005;</span>
495                    </span>`
496                );
497            });
498        } else {
499            $dropdownButton.text('Select Tag');
500        }
501    };
502
503    // Handle individual checkbox selection
504    $('.mintmrm-dropdown-list input[type="checkbox"]').not('#all-items-create').on('change', function() {
505        const $allItemsCheckbox = $('#all-items-create');
506        const $checkboxes = $('.mintmrm-dropdown-list input[type="checkbox"]').not($allItemsCheckbox);
507        const $checkedCheckboxes = $checkboxes.filter(':checked');
508
509        // Update "Select All Items" checkbox
510        if ($checkedCheckboxes.length === $checkboxes.length) {
511            $allItemsCheckbox.prop('checked', true);
512        } else {
513            $allItemsCheckbox.prop('checked', false);
514        }
515
516        updateDropdownButton();
517    });
518
519    // Handle "Select All Items" checkbox
520    $('#all-items-create').on('change', function() {
521        const $checkboxes = $('.mintmrm-dropdown-list input[type="checkbox"]').not(this);
522        $checkboxes.prop('checked', $(this).is(':checked'));
523        updateDropdownButton();
524    });
525
526    // Remove item from button when close icon is clicked
527    $(document).on('click', '.close-list', function() {
528        const $checkbox = $(`input[type="checkbox"][value="${$(this).parent().text().trim()}"]`);
529        $checkbox.prop('checked', false).trigger('change');
530    });
531
532    // Search functionality on input
533    $('.searchbar.mintmrm-dropdown-list input[type="search"]').on('input', function() {
534        const searchValue = $(this).val().toLowerCase();
535        const $items = $('.option-section .single-column');
536        let hasMatch = false;
537
538        $items.each(function() {
539            const itemText = $(this).find('label').text().toLowerCase();
540            const isMatch = itemText.includes(searchValue);
541            $(this).toggle(isMatch);
542            if (isMatch) {
543                hasMatch = true;
544            }
545        });
546
547        // Show "No items found" if no matches
548        if (!hasMatch) {
549            if (!$('.no-items-found').length) {
550                $('.option-section').append('<div class="no-items-found">No items found</div>');
551            }
552        } else {
553            $('.no-items-found').remove();
554        }
555    });
556});

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.