1/** 2 * Algolia search field â autocomplete + Personalization . 3 */ 4(function () { 5 'use strict'; 6 7 var config = window.psAlgoliaSearch; 8 if (!config || !config.appId || !config.apiKey || !config.indexName) return; 9 10 var appId = config.appId; 11 var apiKey = config.apiKey; 12 var indexName = config.indexName; 13 var searchPageUrl = config.searchPageIndexURL || (window.location.pathname + window.location.search); 14 15 function getUserToken() { 16 var key = 'ps_algolia_user_token'; 17 if (config.userToken && config.userToken !== '') { 18 try { 19 localStorage.removeItem(key); 20 } catch (e) {} 21 return String(config.userToken); 22 } 23 try { 24 var existing = localStorage.getItem(key); 25 if (existing) return existing; 26 } catch (e) {} 27 var token = 'guest-' + Math.random().toString(36).slice(2) + Date.now(); 28 try { 29 localStorage.setItem(key, token); 30 } catch (e) {} 31 return token; 32 } 33 34 var userToken = getUserToken(); 35 if (window.aa) { 36 window.aa('init', { appId: appId, apiKey: apiKey, useCookie: false }); 37 window.aa('setUserToken', userToken); 38 } 39 40 var searchClient = window.algoliasearch(appId, apiKey); 41 42 function debounce(fn, delay) { 43 var timeout; 44 return function () { 45 var ctx = this; 46 var args = arguments; 47 clearTimeout(timeout); 48 timeout = setTimeout(function () { fn.apply(ctx, args); }, delay); 49 }; 50 } 51 52 var containers = document.querySelectorAll('.ps-algolia-search-field'); 53 if (!containers.length) return; 54 55 function initInstance(container) { 56 var input = container.querySelector('.ps-algolia-search-field__input'); 57 if (!input) return; 58 59 var suggestionsEl = container.querySelector('.ps-algolia-search-field__suggestions'); 60 var listEl = suggestionsEl ? suggestionsEl.querySelector('ul') : null; 61 var noResultsEl = container.querySelector('.ps-algolia-search-field__no-results'); 62 63 if (!listEl) return; 64 65 function showSuggestions(hits, queryID) { 66 listEl.innerHTML = ''; 67 if (noResultsEl) noResultsEl.style.display = 'none'; 68 69 var messageLi = document.createElement('li'); 70 messageLi.className = 'ps-algolia-search-field__hint'; 71 messageLi.textContent = 'Press Enter for full search results'; 72 listEl.appendChild(messageLi); 73 74 if (hits && hits.length > 0) { 75 var hitTemplate = window.psAlgoliaHitTemplateCompact || window.psAlgoliaHitTemplate; 76 hits.forEach(function (hit, idx) { 77 var li = document.createElement('li'); 78 li.setAttribute('role', 'option'); 79 li.innerHTML = hitTemplate ? hitTemplate(hit) : ('<a href="' + (hit.permalink || '#') + '">' + (hit.title || '') + '</a>'); 80 var link = li.querySelector('a'); 81 if (link) { 82 li.addEventListener('click', function (e) { 83 e.preventDefault(); 84 if (window.aa && (hit.__queryID || queryID) && hit.objectID) { 85 window.aa('clickedObjectIDsAfterSearch', { 86 index: indexName, 87 eventName: 'Header search click', 88 queryID: hit.__queryID || queryID, 89 objectIDs: [String(hit.objectID)], 90 positions: [hit.__position != null ? hit.__position : idx + 1], 91 userToken: userToken, 92 }); 93 } 94 window.location.href = link.getAttribute('href'); 95 }); 96 } 97 listEl.appendChild(li); 98 }); 99 if (suggestionsEl) { 100 suggestionsEl.style.display = 'block'; 101 suggestionsEl.setAttribute('aria-hidden', 'false'); 102 } 103 } else { 104 if (suggestionsEl) suggestionsEl.style.display = 'block'; 105 if (noResultsEl) { 106 noResultsEl.style.display = 'block'; 107 noResultsEl.setAttribute('aria-hidden', 'false'); 108 } 109 } 110 } 111 112 function hideSuggestions() { 113 if (suggestionsEl) { 114 suggestionsEl.style.display = 'none'; 115 suggestionsEl.setAttribute('aria-hidden', 'true'); 116 } 117 if (noResultsEl) { 118 noResultsEl.style.display = 'none'; 119 noResultsEl.setAttribute('aria-hidden', 'true'); 120 } 121 } 122 123 function doSearch(query) { 124 if (query.length < 2) { 125 hideSuggestions(); 126 return; 127 } 128 var index = searchClient.initIndex(indexName); 129 index.search(query, { hitsPerPage: 6, clickAnalytics: true, userToken: userToken }).then(function (res) { 130 showSuggestions(res.hits || [], res.queryID); 131 }).catch(function () { 132 showSuggestions([]); 133 }); 134 } 135 136 var debouncedSearch = debounce(doSearch, 500); 137 138 input.addEventListener('input', function () { 139 debouncedSearch(this.value.trim()); 140 }); 141 142 function submitSearch() { 143 var q = input.value.trim(); 144 if (q) { 145 var url = searchPageUrl.indexOf('?') !== -1 ? searchPageUrl : searchPageUrl.replace(/\?.*$/, ''); 146 var sep = url.indexOf('?') !== -1 ? '&' : '?'; 147 window.location.href = url + sep + 'query=' + encodeURIComponent(q); 148 } 149 } 150 151 input.addEventListener('keydown', function (e) { 152 if (e.key === 'Enter') { 153 e.preventDefault(); 154 submitSearch(); 155 } 156 }); 157 158 var submitBtn = container.querySelector('.ps-algolia-search-field__submit'); 159 if (submitBtn) { 160 submitBtn.addEventListener('click', function () { 161 submitSearch(); 162 }); 163 } 164 165 document.addEventListener('click', function (e) { 166 if (!container.contains(e.target)) { 167 hideSuggestions(); 168 } 169 }); 170 } 171 172 for (var i = 0; i < containers.length; i++) { 173 initInstance(containers[i]); 174 } 175})();
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.