code.gitea.io/gitea@v1.22.3/web_src/js/features/common-issue-list.js (about) 1 import {isElemHidden, onInputDebounce, submitEventSubmitter, toggleElem} from '../utils/dom.js'; 2 import {GET} from '../modules/fetch.js'; 3 4 const {appSubUrl} = window.config; 5 const reIssueIndex = /^(\d+)$/; // eg: "123" 6 const reIssueSharpIndex = /^#(\d+)$/; // eg: "#123" 7 const reIssueOwnerRepoIndex = /^([-.\w]+)\/([-.\w]+)#(\d+)$/; // eg: "{owner}/{repo}#{index}" 8 9 // if the searchText can be parsed to an "issue goto link", return the link, otherwise return empty string 10 export function parseIssueListQuickGotoLink(repoLink, searchText) { 11 searchText = searchText.trim(); 12 let targetUrl = ''; 13 if (repoLink) { 14 // try to parse it in current repo 15 if (reIssueIndex.test(searchText)) { 16 targetUrl = `${repoLink}/issues/${searchText}`; 17 } else if (reIssueSharpIndex.test(searchText)) { 18 targetUrl = `${repoLink}/issues/${searchText.substr(1)}`; 19 } 20 } else { 21 // try to parse it for a global search (eg: "owner/repo#123") 22 const matchIssueOwnerRepoIndex = searchText.match(reIssueOwnerRepoIndex); 23 if (matchIssueOwnerRepoIndex) { 24 const [_, owner, repo, index] = matchIssueOwnerRepoIndex; 25 targetUrl = `${appSubUrl}/${owner}/${repo}/issues/${index}`; 26 } 27 } 28 return targetUrl; 29 } 30 31 export function initCommonIssueListQuickGoto() { 32 const goto = document.getElementById('issue-list-quick-goto'); 33 if (!goto) return; 34 35 const form = goto.closest('form'); 36 const input = form.querySelector('input[name=q]'); 37 const repoLink = goto.getAttribute('data-repo-link'); 38 39 form.addEventListener('submit', (e) => { 40 // if there is no goto button, or the form is submitted by non-quick-goto elements, submit the form directly 41 let doQuickGoto = !isElemHidden(goto); 42 const submitter = submitEventSubmitter(e); 43 if (submitter !== form && submitter !== input && submitter !== goto) doQuickGoto = false; 44 if (!doQuickGoto) return; 45 46 // if there is a goto button, use its link 47 e.preventDefault(); 48 window.location.href = goto.getAttribute('data-issue-goto-link'); 49 }); 50 51 const onInput = async () => { 52 const searchText = input.value; 53 // try to check whether the parsed goto link is valid 54 let targetUrl = parseIssueListQuickGotoLink(repoLink, searchText); 55 if (targetUrl) { 56 const res = await GET(`${targetUrl}/info`); // backend: GetIssueInfo, it only checks whether the issue exists by status code 57 if (res.status !== 200) targetUrl = ''; 58 } 59 // if the input value has changed, then ignore the result 60 if (input.value !== searchText) return; 61 62 toggleElem(goto, Boolean(targetUrl)); 63 goto.setAttribute('data-issue-goto-link', targetUrl); 64 }; 65 66 input.addEventListener('input', onInputDebounce(onInput)); 67 onInput(); 68 }