function minQueryLen(query) { query = query.trim(); const query_is_float = parseFloat(query); const min_query_length = query_is_float ? 1 : 2; return min_query_length; } function findQuery(query = 'query') { const url_params = new URLSearchParams(window.location.search); return url_params.has(query) ? url_params.get(query) : empty_string; } function search(index, scope = null, passive = false) { scope = search_scope_global ? null : scope; if(search_term.length) { let raw_results = index; if(!algolia_config.on) { raw_results = index.search(search_term); raw_results = raw_results.map(function(result){ const score = result.score; const result_item = result.item; result_item.score = (parseFloat(score) * 50).toFixed(0); return result_item; }) } if(scope) { raw_results = raw_results.filter(result_item => { return result_item.section == scope; }); } passive ? searchResults(raw_results, search_term, true) : searchResults(raw_results, search_term); } else { passive ? searchResults([], empty_string, true) : searchResults(); } } function liveSearch(index) { if (search_field) { let search_scope = search_field.dataset.scope; search(index, search_scope); search_scope = search_scope_global ? null : search_scope; if(!search_page_element) { search_field.addEventListener('keyup', function(event){ search_term = search_field.value.trim().toLowerCase(); if(search_term.length && event.keyCode === 13) { const scope_parameter = search_scope ? `&scope=${search_scope}` : empty_string; window.location.href = new URL(`search/?query=${search_term}${ scope_parameter }`, root_url).href; } }); } } } function searchResults(results=[], query=empty_string, passive = false) { let results_fragment = new DocumentFragment(); let show_results = elem('.search_results'); if(passive || search_page_element) { show_results = search_page_element; } emptyEl(show_results); const query_len = query.length; const required_query_len = minQueryLen(query); if(results.length && query_len >= required_query_len) { let results_title = createEl('h3'); results_title.className = 'search_title'; results_title.innerText = quick_links; let go_back_button = createEl('button'); go_back_button.textContent = 'Go Back'; go_back_button.className = go_back_class; if(passive) { results_title.innerText = search_results_label; } if(!search_page_element) { results = results.slice(0,8); } else { // results_fragment.appendChild(go_back_button); results = results.slice(0,12); } results_fragment.appendChild(results_title); results.forEach(function(result){ let item = createEl('a'); item.href = `${result.link}?query=${query}`; item.className = search_result_class; item.style.order = result.score; if (passive) { pushClass(item, 'passive'); let item_title = createEl('h3'); item_title.textContent = result.title; item.appendChild(item_title); let item_description = createEl('p'); // position of first search term instance let query_instance = result.body.indexOf(query); item_description.textContent = `${result.body.substring(query_instance, query_instance + 200)}`; item.appendChild(item_description); } else { item.textContent = result.title; } results_fragment.appendChild(item); }); } if(show_results) { let results_title_contents = empty_string; if(query_len >= required_query_len) { results_title_contents = !results.length ? `${no_matches_found}` : empty_string; } else { results_title_contents = `` } show_results.innerHTML = results_title_contents; show_results.appendChild(results_fragment); } } function passiveSearch(index) { if(search_page_element) { search_term = findQuery(); const search_scope = findQuery('scope'); search(index, search_scope, true); } } function hasSearchResults() { const results = elem('.results'); return results ? [results, results.innerHTML.length] : false; } function clearSearchResults() { let results = hasSearchResults(); if(results) { results = results[0]; results.innerHTML = empty_string; elem(search_field_class).value = empty_string; } } function onEscape(fn){ window.addEventListener('keydown', event => event.code === "Escape" ? fn() : false); } function initFuseSearch(manual = true) { const page_language = document.documentElement.lang; const search_index = `${ page_language === 'en' ? empty_string : page_language}/index.json`; fetch(new URL(search_index, root_url).href) .then(response => response.json()) .then(function(search_data) { search_data = search_data.length ? search_data : []; const fuse_index = new Fuse(search_data, search_options); manual ? liveSearch(fuse_index) : passiveSearch(fuse_index); }) .catch((error) => console.error(error)); } function initAlgoliaSearch(manual = true) { const algolia_client = algoliasearch(algolia_config.id, algolia_config.key); const algolia_index = algolia_client.initIndex(algolia_config.index); algolia_index.search(search_term, { attributesToRetrieve: search_keys.slice(0,5), hitsPerPage: 12, }).then(({ hits }) => { manual ? liveSearch(hits) : passiveSearch(hits); }); } function tabOverSearchResults() { search_field.addEventListener('keydown', function (e) { // Prevent curet from moving when up or down is pressed if (e.keyCode === 38 || e.keyCode === 40 || e.keyCode === 13) { e.preventDefault(); return; } }); search_field.addEventListener('keyup', function (e) { if (e.keyCode !== 38 && e.keyCode !== 40 && e.keyCode !== 13) { return } e.preventDefault(); var results = e.target.parentNode.getElementsByClassName('search_result'); if (results.length === 0) { return; } // Find the currently selected result and select the next or previous one var selected = -1; for (var i = 0; i < results.length; i++) { if (results[i].classList.contains('active')) { selected = i; results[i].classList.remove('active'); break; } } if (e.keyCode === 38) { // For up arrow select the previous result selected = selected === -1 ? results.length - 1 : selected - 1; if (selected < 0) { selected = results.length - 1; } results[selected].classList.add('active'); return; } else if (e.keyCode === 40) { // For down arrow select the next result selected = selected === -1 ? 0 : selected + 1; if (selected === results.length) { selected = 0; } results[selected].classList.add('active'); return; } window.location.href = results[selected === -1 ? 0 : selected].href; return; }); } function initializeSearch() { let main = elem('main'); main = main ? main : elem('.main'); search_field.addEventListener('input', function() { search_term = search_field.value.trim().toLowerCase(); algolia_config.on ? initAlgoliaSearch() : initFuseSearch(); }); if (search_page_element) { algolia_config.on ? initAlgoliaSearch(false) : initFuseSearch(false); } wrapText(findQuery(), main); onEscape(clearSearchResults); window.addEventListener('click', function(event){ const target = event.target; const is_search = target.closest(search_class) || target.matches(search_class); !is_search && !search_page_element ? clearSearchResults() : false; }); tabOverSearchResults(); } window.addEventListener('load', () => initializeSearch());