Tue, 11 Mar 2025 17:03:01 +0100
Added tag v1.5.0 for changeset 817905c30514
/* * Copyright 2025 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ function debounce(func){ let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, 300); }; } let searchBoxOldContent = ''; function issueSearchImpl(elementId, project) { const searchBox = document.getElementById(elementId); if (searchBoxOldContent !== searchBox.value) { searchBoxOldContent = searchBox.value; const req = new XMLHttpRequest(); req.addEventListener("load", (evt) => { const dataList = document.getElementById(elementId+'-list'); dataList.innerHTML = ''; JSON.parse(evt.target.responseText).forEach(function(item){ const option = document.createElement('option'); option.value = item; dataList.appendChild(option); }); }); let url = baseHref+'issues/search?q='+encodeURIComponent(searchBox.value); if (project > 0) url+='&p='+project; req.open("GET", url); req.send(); } } const issueSearch = debounce((elementId, project = 0) => issueSearchImpl(elementId, project)) function configureSearchBox(elementId, project, navigateOnEnter = false) { const searchBox = document.getElementById(elementId); searchBox.addEventListener('change', () => issueSearch(elementId, project)); if (navigateOnEnter) { searchBox.addEventListener('keyup', (evt) => { if (evt.code === 'Enter' || evt.code === 'NumpadEnter') { let stext = searchBox.value.trim() if (stext.length === 0) return; if (stext[0] === '#') stext = stext.substring(1); const snum = Number.parseInt(stext.split(' ')[0], 10); if (snum !== Number.NaN) { location.assign(baseHref + 'issues/' + snum + '?in_project=true'); } } else { issueSearch(elementId, project); } }) } else { searchBox.addEventListener('keyup', () => issueSearch(elementId, project)); } } // configure the global search box window.addEventListener('load', () => configureSearchBox('search-box', 0, true));