1jQuery(function ($) { 2 // Resolve a reCAPTCHA token, or '' when reCAPTCHA isn't configured. 3 // Empty key + empty token + the server-side WP_DEBUG fallback keeps 4 // local-dev installs functional without a real Google site key 5 // (production keys are domain-restricted and won't issue tokens 6 // for localhost). On production, an empty key means the admin 7 // hasn't set RECAPTCHA_SITE_KEY in wp-config.php â the admin 8 // notice flags it. 9 function gcGetRecaptchaToken(action) { 10 return new Promise(function (resolve) { 11 var key = (window.SmartSearch && SmartSearch.siteKey) || ''; 12 if (!key || typeof grecaptcha === 'undefined') { 13 resolve(''); 14 return; 15 } 16 grecaptcha.ready(function () { 17 grecaptcha.execute(key, {action: action}).then(resolve, function () { resolve(''); }); 18 }); 19 }); 20 } 21 22 let timer = null; 23 let xhr = null; 24 $('#search-input').on('keyup', function () { 25 let query = $(this).val(); 26 if (query.length < 3) { 27 $('#smart-search-results').empty().hide(); 28 return; 29 } 30 clearTimeout(timer); 31 timer = setTimeout(function () { 32 if (xhr) { 33 xhr.abort(); 34 } 35 gcGetRecaptchaToken('search').then(function (token) { 36 xhr = $.ajax({ 37 url: SmartSearch.ajaxurl, 38 type: 'POST', 39 dataType: 'json', 40 data: { 41 action: 'smart_search_autocomplete', 42 recaptcha_token: token, 43 term: query 44 }, 45 success: function (response) { 46 let container = $('#smart-search-results'); 47 container.empty(); 48 if (!response.length) { 49 container.hide(); 50 return; 51 } 52 response.forEach(function (item) { 53 let html = 54 '<li class="list-group-item">' + 55 '<div class="fw-bold"><a href="' + item.url + '">' + item.icon + ' ' + item.title + '</a></div>' + 56 item.breadcrumbs + 57 '</li>'; 58 container.append(html); 59 }); 60 container.show(); 61 } 62 }); 63 }); 64 }, 300); 65 }); 66 $('#ajax-search-form').on('submit', function(e){ 67 e.preventDefault(); 68 // No result page configured â submit is a no-op. The shortcode 69 // also disables the button visually for visitors and shows an 70 // admin warning, but guarding here too makes the failure mode 71 // explicit if the markup is ever bypassed. 72 if (window.SmartSearch && SmartSearch.hasResultPage === false) { 73 return; 74 } 75 let searchTerm = $('#search-input').val(); 76 let dateFrom = $('#search-date-from').val(); 77 let dateTo = $('#search-date-to').val(); 78 $.ajax({ 79 url: SearchToken.ajaxurl, 80 type: 'POST', 81 dataType: 'json', 82 data: { 83 action: 'create_search_token', 84 search_term: searchTerm, 85 date_from: dateFrom, 86 date_to: dateTo 87 }, 88 success: function(response){ 89 if(response.redirect){ 90 window.location.href = response.redirect; 91 } 92 } 93 }); 94 }); 95}); 96jQuery(function ($) { 97 98 const input = $('#search-input'); 99 const clearBtn = $('#smart-search-clear'); 100 const results = $('#smart-search-results'); 101 102 input.on('keyup', function () { 103 104 if ($(this).val().length > 0) { 105 clearBtn.removeClass('d-none'); 106 } else { 107 clearBtn.addClass('d-none'); 108 } 109 110 }); 111 112 clearBtn.on('click', function () { 113 114 input.val('').focus(); 115 results.empty().hide(); 116 clearBtn.addClass('d-none'); 117 118 }); 119 120});
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.