PageSourceSearch

https://rentalplaza.in/wp-content/plugins/woo-location-filter/assets/js/wlf-location-popup.js?ver=1790855852

js rentalplaza.in collected 2026-10-01 12:00:52 UTC 35,680 bytes, 899 lines download raw bytes

1jQuery(document).ready(function ($) {
2    var locationPopupEnabled = wlf_front_vars.showLocationPopup === 'yes';
3    var locationPopupClosed = getCookie('wlf_location_popup_closed') === 'true';
4    var locationCookieSet = !!getCookie('wlf_location_cookies');
5
6    const allLocationsInTitle = wlf_front_vars.allLocationsInTitle || 'All Locations in';
7    const parentContainer = $('.wlf-parent-locations-container');
8    const childContainer = $('.wlf-child-locations-container');
9
10    var wlfChildViewStack = [];
11
12    function wlfGetChildList() {
13        return $('.wlf-child-locations-container').find('ul.wlf-child-location-list');
14    }
15
16    function wlfUpdatePopupBackButton() {
17        var isChildView = wlfChildViewStack.length > 0;
18
19        $('.wlf-location-popup-back-btn').toggle(isChildView);
20        $('.wlf-location-popup-header-icon').toggle(!isChildView);
21        $('.wlf-location-popup-header-mobile-icon').toggle(!isChildView);
22    }
23
24    function wlfShowMainLocationView() {
25        wlfChildViewStack = [];
26        $('.wlf-location-search-results').remove();
27        $('#wlf-no-results').hide();
28        wlfGetChildList().empty();
29        childContainer.hide();
30        parentContainer.show();
31        wlfUpdatePopupBackButton();
32    }
33
34    function wlfEnterChildLocationView(childContent) {
35        var $childList = wlfGetChildList();
36
37        if (childContainer.is(':visible')) {
38            wlfChildViewStack.push($childList.html());
39        } else {
40            wlfChildViewStack.push(null);
41        }
42
43        parentContainer.hide();
44        $('.wlf-location-search-results').remove();
45        $('#wlf-no-results').hide();
46        $childList.html(childContent);
47        childContainer.show();
48        wlfUpdatePopupBackButton();
49    }
50
51    $(document).on('click', '.wlf-location-popup-back-btn', function (event) {
52        event.preventDefault();
53
54        if (!wlfChildViewStack.length) {
55            wlfShowMainLocationView();
56            return;
57        }
58
59        var previousView = wlfChildViewStack.pop();
60
61        if (previousView === null || typeof previousView === 'undefined') {
62            wlfShowMainLocationView();
63            return;
64        }
65
66        parentContainer.hide();
67        wlfGetChildList().html(previousView);
68        childContainer.show();
69        wlfUpdatePopupBackButton();
70    });
71
72
73    // ==========================================
74    // URL Routing & Cookie Sync Logic
75    // Moved from PHP to JS for stability
76    // ==========================================
77    var LOCATION_SLUGS = wlf_front_vars.locationSlugs || [];
78    var LOCATION_LABELS = { 'all': 'All' };
79
80    function wlfRememberLocationLabel(slug, name) {
81        slug = (slug || '').toString().trim().toLowerCase();
82        name = (name || '').toString().trim();
83
84        if (slug && name) {
85            LOCATION_LABELS[slug] = name;
86        }
87    }
88
89    function wlfGetDefaultLocationLabel() {
90        return $('.wlf-selected-location-name').first().data('default-location-label') || 'Select your location';
91    }
92
93    function wlfHydrateLocationLabelsFromDom() {
94        $('.wlf-featured-location-list li, .wlf-non-featured-location-list li, .wlf-child-locations-container li, .wlf-location-search-results li').each(function() {
95            var slug = $(this).data('location');
96            var name = $(this).find('.wlf-featured-location-name, .wlf-non-featured-location-name, .wlf-child-location-name, .wlf-search-result-location-name').first().text().trim();
97
98            wlfRememberLocationLabel(slug, name);
99        });
100
101        wlfRememberLocationLabel($('#wlf-location-popup').data('selected-location-slug'), $('#wlf-location-popup').data('selected-location-name'));
102    }
103
104    // Dynamically populate labels from DOM payload.
105    wlfHydrateLocationLabelsFromDom();
106
107    // Ensure SITE_BASE is correctly fetched
108    var SITE_BASE = '';
109    try {
110        var siteUrl = new URL(wlf_front_vars.siteurl);
111        SITE_BASE = siteUrl.pathname.replace(/\/+$/, '');
112    } catch(e) {
113        SITE_BASE = '';
114    }
115
116    var switchingLocationUntil = 0;
117
118    function lc(s) {
119        return (s || '').toString().trim().toLowerCase();
120    }
121
122    function getLocationCookieDomain() {
123        var host = window.location.hostname.toLowerCase();
124
125        if (!host || host === 'localhost' || /^[0-9.]+$/.test(host)) {
126            return '';
127        }
128
129        if (host.indexOf('www.') === 0) {
130            host = host.substring(4);
131        }
132
133        return '.' + host;
134    }
135
136    function setCookie(name, valLC, days) {
137        days = days || 7;
138        const date = new Date();
139        date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
140
141        var value = name + '=' + encodeURIComponent(lc(valLC)) +
142            ';expires=' + date.toUTCString() +
143            ';path=/' +
144            ';samesite=Lax' +
145            (window.location.protocol === 'https:' ? ';secure' : '');
146
147        // Host-only cookie for current host.
148        document.cookie = value;
149
150        // Parent-domain cookie so both www and non-www can read it.
151        var cookieDomain = getLocationCookieDomain();
152        if (cookieDomain) {
153            document.cookie = value + ';domain=' + cookieDomain;
154        }
155    }
156
157    function getCookie(name) {
158        const cookies = document.cookie.split('; ');
159        var found = null;
160
161        for (let i = 0; i < cookies.length; i++) {
162            const parts = cookies[i].split('=');
163            if (parts[0] === name) {
164                found = decodeURIComponent(parts.slice(1).join('=') || '');
165            }
166        }
167
168        return found;
169    }
170
171    function deleteCookie(name) {
172        var expired = name + '=;path=/;expires=Thu, 01 Jan 1970 00:00:00 UTC;' +
173            (window.location.protocol === 'https:' ? ';secure' : '');
174
175        // Delete current host cookie.
176        document.cookie = expired;
177
178        // Delete parent-domain cookie.
179        var cookieDomain = getLocationCookieDomain();
180        if (cookieDomain) {
181            document.cookie = expired + ';domain=' + cookieDomain;
182        }
183
184        // Delete explicit current hostname domain cookie, if any.
185        if (window.location.hostname) {
186            document.cookie = expired + ';domain=' + window.location.hostname;
187        }
188    }
189
190    function looksLikeFile(pathname) {
191        return /\.[a-z0-9]{1,5}(?:$|\?)/i.test(pathname);
192    }
193
194    function isLocationSlug(segLC) {
195        segLC = lc(segLC);
196        for (var i = 0;
196 i < LOCATION_SLUGS.length; i++) {
197            if (lc(LOCATION_SLUGS[i]) === segLC) return true;
198        }
199        return false;
200    }
201
202    function getCurrentUrlParts() {
203        var url = new URL(window.location.href);
204        var rawPath = url.pathname;
205        var rel = '';
206
207        if (SITE_BASE && rawPath.indexOf(SITE_BASE + '/') === 0) {
208            rel = rawPath.substring((SITE_BASE + '/').length);
209        } else if (SITE_BASE && rawPath === SITE_BASE) {
210            rel = '';
211        } else {
212            rel = rawPath.replace(/^\/+/, '');
213        }
214
215        var relParts = rel ? rel.split('/') : [];
216        var firstSegLC = lc(relParts[0] || '');
217
218        return {
219            url: url,
220            rawPath: rawPath,
221            rel: rel,
222            relParts: relParts,
223            firstSegLC: firstSegLC
224        };
225    }
226
227    function updateSelectedUIFromSlug(slugLC) {
228        slugLC = lc(slugLC);
229        wlfHydrateLocationLabelsFromDom();
230
231        var labelNode = $('.wlf-selected-location-name');
232        if (labelNode.length) {
233            if (slugLC && slugLC !== 'all') {
234                var label = LOCATION_LABELS[slugLC];
235                labelNode.text(label || wlfGetDefaultLocationLabel());
236            } else {
237                labelNode.text(wlfGetDefaultLocationLabel());
238            }
239        }
240
241        var lists = ['.wlf-featured-location-list li', '.wlf-non-featured-location-list li', '.wlf-child-locations-container li'];
242        $(lists.join(', ')).each(function() {
243            $(this).find('.wlf-selected-location-indicator').html('');
244            var s = lc($(this).data('location') || '');
245            if ((slugLC && s === slugLC) || (!slugLC && s === 'all')) {
246                $(this).find('.wlf-selected-location-indicator').html('<i class="fas fa-circle"></i>');
247            }
248        });
249
250        checkLocationType(slugLC);
251    }
252
253    function getRelWithoutLocationPrefix(rel) {
254        rel = (rel || '').replace(/^\/+|\/+$/g, '');
255        if (!rel) return '';
256
257        var parts = rel.split('/');
258        var first = lc(parts[0] || '');
259
260        if (isLocationSlug(first)) {
261            parts.shift();
262        }
263
264        return parts.join('/');
265    }
266
267    function buildPrefixedPath(slugLC, relWithoutPrefix) {
268        slugLC = lc(slugLC);
269        relWithoutPrefix = (relWithoutPrefix || '').replace(/^\/+|\/+$/g, '');
270
271        var base = SITE_BASE ? SITE_BASE.replace(/\/+$/, '') : '';
272
273        if (!slugLC || slugLC === 'all') {
274            var plainPath = base + (relWithoutPrefix ? '/' + relWithoutPrefix : '/');
275            return plainPath.replace(/([^:])\/{2,}/g, '$1/');
276        }
277
278        var newRel = slugLC + (relWithoutPrefix ? '/' + relWithoutPrefix : '');
279        var newPath = base + '/' + newRel;
280        return newPath.replace(/([^:])\/{2,}/g, '$1/');
281    }
282
283    function replaceUrlKeepingQueryHash(newPath) {
284        var url = new URL(window.location.href);
285        var finalUrl = newPath + url.search + url.hash;
286        var currentUrl = url.pathname + url.search + url.hash;
287
288        if (finalUrl !== currentUrl) {
289            history.replaceState(history.state, '', finalUrl);
290        }
291    }
292
293    function navigateToPath(newPath) {
294        var url = new URL(window.location.href);
295        var finalUrl = newPath + url.search + url.hash;
296        var currentUrl = url.pathname + url.search + url.hash;
297
298        if (finalUrl !== currentUrl) {
299            window.location.href = finalUrl;
300        } else {
301            window.location.reload();
302        }
303    }
304
305    function ensureLocationSlugInUrl() {
306        var parts = getCurrentUrlParts();
307        var url = parts.url;
308        var firstSegLC = parts.firstSegLC;
309        var rel = parts.rel;
310        var cookieLC = lc(getCookie('wlf_location_cookies') || '');
311
312        var assetPrefixes = ['wp-admin', 'wp-includes', 'wp-content', 'wp-json'];
313        if (assetPrefixes.indexOf(firstSegLC) !== -1) return;
314        if (looksLikeFile(url.pathname)) return;
315
316        // During active switching: cookie should win
317        if (Date.now() < switchingLocationUntil) {
318            if (cookieLC && isLocationSlug(cookieLC)) {
319                var relWithoutPrefixDuringSwitch = getRelWithoutLocationPrefix(rel);
320                var pathDuringSwitch = buildPrefixedPath(cookieLC, relWithoutPrefixDuringSwitch);
321                replaceUrlKeepingQueryHash(pathDuringSwitch);
322                updateSelectedUIFromSlug(cookieLC);
323            }
324            return;
325        }
326
327        // Normal browsing: URL wins when it already has valid slug (i.e. Opening an external link)
328        if (isLocationSlug(firstSegLC)) {
329            if (cookieLC !== firstSegLC) {
330                setCookie('wlf_location_cookies', firstSegLC, 7);
331            }
332            updateSelectedUIFromSlug(firstSegLC);
333            return;
334        }
335
336        // If URL has no slug but cookie has one, restore it to URL
337        if (cookieLC && cookieLC !== 'all' && isLocationSlug(cookieLC)) {
338            var relWithoutPrefix = getRelWithoutLocationPrefix(rel);
339            var newPath = buildPrefixedPath(cookieLC, relWithoutPrefix);
340            replaceUrlKeepingQueryHash(newPath);
341            updateSelectedUIFromSlug(cookieLC);
342            return;
343        }
344
345        updateSelectedUIFromSlug('all');
346    }
347
348    function debounce(fn, delay) {
349        var t;
350        return function() {
351            clearTimeout(t);
352            t = setTimeout(fn, delay);
353        };
354    }
355
356    var ensureDebounced = debounce(function() {
357        ensureLocationSlugInUrl();
358    }, 80);
359
360    window.WLF_setSelectedLocation = function(slug, options) {
361        var slugLC = lc(slug);
362        options = options || {};
363
364        if (!slugLC) slugLC = 'all';
365        if (!isLocationSlug(slugLC)) return false;
366
367        switchingLocationUntil = Date.now() + 2000;
368
369        var parts = getCurrentUrlParts();
370        var relWithoutPrefix = getRelWithoutLocationPrefix(parts.rel);
371
372        setCookie('wlf_location_cookies', slugLC, 7);
373        updateSelectedUIFromSlug(slugLC);
374
375        var newPath = buildPrefixedPath(slugLC, relWithoutPrefix);
376
377        if (options.reload === true) {
378            navigateToPath(newPath);
379        } else {
380            replaceUrlKeepingQueryHash(newPath);
381        }
382        return true;
383    };
384
385    if (String(wlf_front_vars.locationInUrl || 'no').toLowerCase() === 'yes') {
386        ensureLocationSlugInUrl();
387
388        window.addEventListener('popstate', ensureDebounced);
389
390        var originalPushState = history.pushState;
391        var originalReplaceState = history.replaceState;
392
393        history.pushState = function() {
394            var result = originalPushState.apply(this, arguments);
395            ensureDebounced();
396            return result;
397        };
398
399        history.replaceState = function() {
400            var result = originalReplaceState.apply(this, arguments);
401            ensureDebounced();
402            return result;
403        };
404
405        $(document).ajaxComplete(ensureDebounced);
406        $(document.body).on('updated_wc_div wc_fragments_loaded wc_fragments_refreshed updated_checkout', ensureDebounced);
407
408        if (window.fetch) {
409            var originalFetch = window.fetch;
410            window.fetch = function() {
411                return originalFetch.apply(this, arguments).then(function(response) {
412                    ensureDebounced();
413                    return response;
414                });
415            };
416        }
417    }
418
419    // ==========================================
420    // Existing Popup Logic
421    // ==========================================
422
423    if (locationPopupEnabled && !locationPopupClosed && !locationCookieSet) {
424        $('.wlf-location-popup').fadeIn();
425    }
426
427    $(document).on('click', '#wlf-selected-location, .wlf-location-single-page-container', function () {
428        wlfShowMainLocationView();
429        $('.wlf-location-popup').fadeIn();
430    });
431
432    // Handle clicking on a parent location
433    $(document).on('click', '.wlf-featured-location-list li, .wlf-non-featured-location-list li', function (event) {
434        event.preventDefault();
435
436        const $clickedElement = $(this);
437        const selectedLocationId = $clickedElement.data('location-id');
438        const selectedLocationSlug = $clickedElement.data('location');
439        const selectedLocationName = $clickedElement.find('.wlf-featured-location-name, .wlf-non-featured-location-name').text().trim();
440        const hasChildren = $clickedElement.data('has-children');
441
442        if (!selectedLocationId) {
443            return;
444        }
445
446        if (hasChildren) {
447            // Fetch child locations via AJAX
448            $.ajax({
449                url: wlf_front_vars.ajaxurl,
450                type: 'POST',
451                data: {
452                    action: 'get_child_locations',
453                    parent_id: selectedLocationId,
454                },
455                success: function (response) {
456                    if (response.success && Array.isArray(response.data) && response.data.length > 0) {
457                        $('.wlf-parent-locations-container').hide();
458                        const childContainer = $('.wlf-child-locations-container');
459                        const childList = childContainer.find('ul.wlf-child-location-list');
460                        let childContent = '';
461                        wlfRememberLocationLabel(selectedLocationSlug, selectedLocationName);
462
463                        // Add "All Locations" option
464                        const isParentSelected = selectedLocationSlug === getCookie('wlf_location_cookies');
465                        childContent += `
466                            <li data-location="${selectedLocationSlug}" data-location-id="${selectedLocationId}" class="all-locations-option">
467                                <div class="wlf-child-top-parent-location-content">
468                                    <div class="wlf-child-top-parent-location-indicator-name">
469                                        <div class="wlf-selected-location-indicator">
470                                            ${isParentSelected ? '<i class="fas fa-circle"></i>' : ''}
471                                        </div>
472                                        <div class="wlf-child-location-name">${allLocationsInTitle} ${selectedLocationName}</div>
473                                    </div>
474                                    <button type="button" class="button wlf-default-clear-location-btn" style="display: none;">Clear</button>
475                                </div>
476                            </li>`;
477
478                        // --------- SORT FEATURED FIRST ---------
479                        const sortedChildren = response.data.slice().sort(function(a, b) {
480                            if (a.is_featured === b.is_featured) return 0;
481                            return a.is_featured ? -1 : 1;
482                        });
483
484                        sortedChildren.forEach(function (child) {
485                            wlfRememberLocationLabel(child.slug, child.name);
486                            const isChildSelected = child.slug === getCookie('wlf_location_cookies');
487                            childContent += `
488                                <li data-location="${child.slug}" data-location-id="${child.term_id}" data-has-children="${child.has_children}">
489                                <div class="wlf-child-location-content">
490                                    <div class="wlf-child-location-image-name-container">
491                                        ${child.image ? `<div class="wlf-child-location-image-container"><img src="${child.image}" alt="${child.name}"></div>` : ''}
492                                        <div class="wlf-child-location-name">${child.name}</div>
493                                    </div>
494                                    <div class="wlf-location-indicators">
495                                        <div class="wlf-selected-location-indicator">
496                                            ${isChildSelected ? '<i class="fas fa-circle"></i>' : ''}
497                                        </div>
498                                        ${child.has_children ? '<div class="wlf-has-children-indicator"><i class="fas fa-angle-right"></i></div>' : ''}
499                                    </div>
500                                </div>
501                                </li>`;
502                        });
503
504                        wlfEnterChildLocationView(childContent);
505                    }
506                },
507                error: function (error) { }
508            });
509        } else {
510            setSelectedLocation(selectedLocationSlug);
511        }
512    });
513
514    // Handle clicking on a child location or "All Locations"
515    $(document).on('click', '.wlf-child-locations-container li', function () {
516        const $clickedElement = $(this);
517        const selectedLocationId = $clickedElement.data('location-id');
518        const selectedLocationSlug = $clickedElement.data('location');
519        const selectedLocationName = $clickedElement.find('.wlf-child-location-name').text().trim();
520        const hasChildren = $clickedElement.data('has-children');
521
522        if (hasChildren) {
523            $.ajax({
524                url: wlf_front_vars.ajaxurl,
525                type: 'POST',
526                data: {
527                    action: 'get_child_locations',
528                    parent_id: selectedLocationId,
529                },
530                success: function (response) {
531                    if (response.success && Array.isArray(response.data) && response.data.length > 0) {
532                        const childContainer = $('.wlf-child-locations-container');
533                        const childList = childContainer.find('ul.wlf-child-location-list');
534                        let childContent = '';
535                        wlfRememberLocationLabel(selectedLocationSlug, selectedLocationName);
536
537                        // Add "All Locations" option
538                        const isChildSelected = selectedLocationSlug === getCookie('wlf_location_cookies');
539                        childContent += `
540                            <li data-location="${selectedLocationSlug}" data-location-id="${selectedLocationId}" class="all-locations-option">
541                                <div class="wlf-child-top-parent-location-content">
542                                    <div class="wlf-child-top-parent-location-indicator-name">
543                                        <div class="wlf-selected-location-indicator">
544                                            ${isChildSelected ? '<i class="fas fa-circle"></i>' : ''}
545                                        </div>
546                                        <div class="wlf-child-location-name">${allLocationsInTitle} ${selectedLocationName}</div>
547                                    </div>
548                                    <button type="button" class="button wlf-default-clear-location-btn" style="display: none;">Clear</button>
549                                </div>
550                            </li>`;
551
552                        // --------- SORT FEATURED FIRST ---------
553                        const sortedChildren = response.data.slice().sort(function(a, b) {
554                            if (a.is_featured === b.is_featured) return 0;
555                            return a.is_featured ? -1 : 1;
556                        });
557
558                        sortedChildren.forEach(function (child) {
559                            wlfRememberLocationLabel(child.slug, child.name);
560                            const isChildSelected = child.slug === getCookie('wlf_location_cookies');
561                            childContent += `
562                                <li data-location="${child.slug}" data-location-id="${child.term_id}" data-has-children="${child.has_children}">
563                                <div class="wlf-child-location-content">
564                                    <div class="wlf-child-location-image-name-container">
565                                        ${child.image ? `<div class="wlf-child-location-image-container"><img src="${child.image}" alt="${child.name}"></div>` : ''}
566                                        <div class="wlf-child-location-name">${child.name}</div>
567                                    </div>
568                                    <div class="wlf-location-indicators">
569                                        <div class="wlf-selected-location-indicator">
570                                            ${isChildSelected ? '<i class="fas fa-circle"></i>' : ''}
571                                        </div>
572                                        ${child.has_children ? '<div class="wlf-has-children-indicator"><i class="fas fa-angle-right"></i></div>' : ''}
573                                    </div>
574                                </div>
575                                </li>`;
576                        });
577
578                        wlfEnterChildLocationView(childContent);
579                    }
580                },
581                error: function (error) { }
582            });
583        } else {
584            setSelectedLocation(selectedLocationSlug);
585        }
586    });
587
588    // Handle location search
589    $('#wlf-location-search').on('input', function () {
590        const searchTerm = $(this).val().trim();
591        $('.wlf-location-search-results').remove();
592        $('#wlf-no-results').hide();
593        wlfShowMainLocationView();
594
595        if (searchTerm.length < 2) return;
596
597        parentContainer.hide();
598        childContainer.hide();
599
600        $.ajax({
601            url: wlf_front_vars.ajaxurl,
602            type: 'POST',
603            data: {
604                action: 'search_locations',
605                search: searchTerm,
606            },
607            success: function (response) {
608                $('.wlf-location-search-results').remove();
609
610                if (response.success && Array.isArray(response.data)) {
611                    const resultsContainer = $('<ul class="wlf-location-search-results"></ul>');
612                    if (response.data.length > 0) {
613                        response.data.forEach(function (location) {
614                            wlfRememberLocationLabel(location.slug, location.name);
615                            const listItem = `
616                                <li data-location="${location.slug}" data-location-id="${location.term_id}">
617                                    <div class="wlf-search-result-location-name-image-container">
618                                        ${location.image ? `<div class="wlf-search-result-location-image-container"><img src="${location.image}" alt="${location.name}" /></div>` : ''}
619                                        <div class="wlf-search-result-location-name">${location.name}</div>
620                                    </div>
621                                </li>
622                            `;
623                            resultsContainer.append(listItem);
624                        });
625                        $('#wlf-location-popup').find('.wlf-search-container').after(resultsContainer);
626                    } else {
627                        $('#wlf-no-results').show();
628                    }
629                }
630            },
631            error: function () {
632                console.error('Error fetching search results');
633            },
634        });
635    });
636
637    // Check whether the selected location is featured or non-featured
638    function checkLocationType(selectedLocation) {
639        var isFeatured = false;
640        var isNonFeatured = false;
641
642        $('.wlf-featured-location-list li').each(function () {
643            if ($(this).data('location') === selectedLocation) {
644                isFeatured = true;
645            }
646        });
647
648        $('.wlf-non-featured-location-list li').each(function () {
649            if ($(this).data('location') === selectedLocation) {
650                isNonFeatured = true;
651            }
652        });
653
654        if (isFeatured) {
655            $('.wlf-clear-featured-selected-location-button').show();
656            $('.wlf-clear-non-featured-selected-location-button').hide();
657        } else if (isNonFeatured) {
658            $('.wlf-clear-featured-selected-location-button').hide();
659            $('.wlf-clear-non-featured-selected-location-button').show();
660        } else {
661            $('.wlf-clear-featured-selected-location-button, .wlf-clear-non-featured-selected-location-button').hide();
662        }
663    }
664
665    var selectedLocation = getCookie('wlf_location_cookies');
666    if (selectedLocation) {
667        checkLocationType(selectedLocation);
668    }
669
670    $(document).on('click', '.wlf-clear-featured-selected-location-button, .wlf-clear-non-featured-selected-location-button', function () {
671        var locationInUrlEnabled =
672            String((wlf_front_vars && wlf_front_vars.locationInUrl) || 'no').toLowerCase() === 'yes';
673    
674        if (locationInUrlEnabled && typeof window.WLF_setSelectedLocation === 'function') {
675            window.WLF_setSelectedLocation('all', { reload: true });
676            return;
677        }
678    
679        deleteCookie('wlf_location_cookies');
680        location.reload();
681    });
682
683    $(document).on('click', '.wlf-location-search-results li', function () {
684        const selectedLocationSlug = $(this).data('location');
685        if (!selectedLocationSlug) return;
686        setSelectedLocation(selectedLocationSlug);
687    });
688
689    function setSelectedLocation(slug) {
690        slug = (slug || '').toString().trim().toLowerCase();
691    
692        var locationInUrlEnabled =
693            String((wlf_front_vars && wlf_front_vars.locationInUrl) || 'no').toLowerCase() === 'yes';
694    
695        // close popup immediately for better UX
696        $('.wlf-location-popup').fadeOut();
697    
698        // when URL mode is enabled, delegate everything to the central helper
699        if (locationInUrlEnabled && typeof window.WLF_setSelectedLocation === 'function') {
700            window.WLF_setSelectedLocation(slug, { reload: true });
701            return;
702        }
703    
704        // fallback when location in URL is disabled
705        setCookie('wlf_location_cookies', slug, 7);
706    
707        window.location.reload();
708    }
709
710    $(document).on('click', '.wlf-location-popup-close-btn', function () {
711        $('.wlf-location-popup').fadeOut();
712        wlfShowMainLocationView();
713        setCookie('wlf_location_popup_closed', 'true', 7);
714    });
715});
716
717/* Woo Location Filter - Frontend auto location detect */
718jQuery(function ($) {
719    if (typeof wlf_front_vars === 'undefined' || String(wlf_front_vars.autoLocationDetect || 'no').toLowerCase() !== 'yes') {
720        return;
721    }
722
723    var $detectWrapper = $('.wlf-detect-my-location-btn-wrapper');
724    if ($detectWrapper.length && !$detectWrapper.find('.wlf-detect-my-location-btn').length) {
725        $detectWrapper.html('<button type="button" class="button wlf-detect-my-location-btn"><i class="fas fa-location-arrow"></i><span>Detect my location</span></button>');
726    }
727
728    function wlfSetDetectButtonState(isLoading, text) {
729        var $btn = $('.wlf-detect-my-location-btn');
730        if (!$btn.length) {
731            return;
732        }
733
734        if (!$btn.data('default-text')) {
735            $btn.data('default-text', $.trim($btn.text()) || 'Detect my location');
736        }
737
738        $btn.prop('disabled', !!isLoading).toggleClass('is-loading', !!isLoading);
739        $btn.find('span').text(text || $btn.data('default-text'));
740    }
741
742    function wlfShowNoServicePopup(message) {
743        message = message || 'Sorry, we do not currently provide service at this location. Please choose a nearby location manually.';
744
745        $('.wlf-location-popup').fadeOut(150);
746        $('.wlf-no-service-message').text(message);
747        $('#wlf-no-service-popup').fadeIn(180).css('display', 'flex');
748    }
749
750    function wlfApplyDetectedLocation(locationSlug) {
751        if (!locationSlug) {
752            wlfShowNoServicePopup();
753            return;
754        }
755
756        $('.wlf-location-popup, #wlf-no-service-popup').fadeOut(120);
757
758        if (typeof window.WLF_setSelectedLocation === 'function') {
759            window.WLF_setSelectedLocation(locationSlug, { reload: true });
760            return;
761        }
762
763        // Fallback if the central helper is unavailable.
764        var date = new Date();
765        date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000));
766        document.cookie = 'wlf_location_cookies=' + encodeURIComponent(locationSlug) + ';expires=' + date.toUTCString() + ';path=/;samesite=Lax' + (window.location.protocol === 'https:' ? ';secure' : '');
767        window.location.reload();
768    }
769
770    function wlfCheckCoordinatesAgainstZones(lat, lng, source) {
771        wlfSetDetectButtonState(true, source === 'search' ? 'Checking location...' : 'Detecting...');
772
773        $.ajax({
774            url: wlf_front_vars.ajaxurl,
775            type: 'POST',
776            dataType: 'json',
777            data: {
778                action: 'wlf_detect_location_by_coordinates',
779                nonce: wlf_front_vars.nonce,
780                lat: lat,
781                lng: lng,
782                source: source || 'browser'
783            },
784            success: function (response) {
785                if (response && response.success && response.data && response.data.location_slug) {
786                    wlfApplyDetectedLocation(response.data.location_slug);
787                    return;
788                }
789
790                var message = response && response.data && response.data.message ? response.data.message : '';
791                wlfShowNoServicePopup(message);
792            },
793            error: function () {
794                wlfShowNoServicePopup('Unable to check service availability right now. Please choose your location manually.');
795            },
796            complete: function () {
797                wlfSetDetectButtonState(false);
798            }
799        });
800    }
801
802    $(document).on('click', '.wlf-detect-my-location-btn', function (e) {
803        e.preventDefault();
804
805        if (!navigator.geolocation) {
806            wlfShowNoServicePopup('Your browser does not support location detection. Please choose your location manually.');
807            return;
808        }
809
810        wlfSetDetectButtonState(true, 'Detecting...');
811
812        navigator.geolocation.getCurrentPosition(
813            function (position) {
814                wlfCheckCoordinatesAgainstZones(position.coords.latitude, position.coords.longitude, 'browser');
815            },
816            function () {
817                wlfSetDetectButtonState(false);
818                wlfShowNoServicePopup('Location permission was denied or unavailable. Please choose your location manually.');
819            },
820            {
821                enableHighAccuracy: true,
822                timeout: 15000,
823                maximumAge: 300000
824            }
825        );
826    });
827
828    $(document).on('click', '.wlf-no-service-popup-close', function () {
829        $('#wlf-no-service-popup').fadeOut(150);
830    });
831
832    function wlfOpenManualLocationPopupFromNoService() {
833        $('.wlf-location-search-results').remove();
834        $('#wlf-no-results').hide();
835        $('#wlf-location-search').val('');
836    
837        $('.wlf-child-location-list').empty();
838        $('.wlf-child-locations-container').hide();
839        $('.wlf-parent-locations-container').show();
840        $('.wlf-location-popup-back-btn').hide();
841        $('.wlf-location-popup-header-icon').show();
842        $('.wlf-location-popup-header-mobile-icon').show();
843    
844        $('#wlf-no-service-popup').fadeOut(150, function () {
845            $('#wlf-location-popup').fadeIn(180).css('display', 'flex');
846    
847            setTimeout(function () {
848                $('#wlf-location-search').trigger('focus');
849            }, 220);
850        });
851    }
852    
853    $(document).on('click', '.wlf-no-service-choose-location', function (e) {
854        e.preventDefault();
855        wlfOpenManualLocationPopupFromNoService();
856    });
857
858    async function wlfInitGooglePlacesSearch() {
859        if (!$('#wlf-location-search').length) {
860            return;
861        }
862
863        if (typeof google === 'undefined' || !google.maps || !google.maps.importLibrary) {
864            return;
865        }
866
867        try {
868            await google.maps.importLibrary('places');
869            var input = document.getElementById('wlf-location-search');
870            var autocomplete = new google.maps.places.Autocomplete(input, {
871                fields: ['geometry', 'name', 'formatted_address'],
872                types: ['geocode']
873            });
874
875            autocomplete.addListener('place_changed', function () {
876                var place = autocomplete.getPlace();
877                if (!place || !place.geometry || !place.geometry.location) {
878                    return;
879                }
880
881                // Remove manual AJAX suggestions when a Google place is selected.
882                $('.wlf-location-search-results').remove();
883                $('#wlf-no-results').hide();
884
885                wlfCheckCoordinatesAgainstZones(
886                    place.geometry.location.lat(),
887                    place.geometry.location.lng(),
888                    'search'
889                );
890            });
891        } catch (error) {
892            if (window.console && console.warn) {
893                console.warn('WLF Google Places search could not be initialized:', error);
894            }
895        }
896    }
897
898    wlfInitGooglePlacesSearch();
899});

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.