diff options
feat: permalinking
-rw-r--r-- | cgit.js | 74 |
1 files changed, 71 insertions, 3 deletions
@@ -1,4 +1,72 @@ // To use this, add this to /var/lib/git/static/cgit.js and set js=/cgit.js in your cgitrc. -if ((/\/[^/]+\.git\/tree\/.*/iu).test(location.pathname)) { - console.log('tree') -}
\ No newline at end of file + +// Check if in repo +if (/\/[^/]+\.git\/.*/iu.test(location.pathname)) { + // Get repo + const repo = location.pathname.match(/\/([^/]+\.git)\/.*/iu)?.[1]; + // Get commit + const get_commit = async () => { + const commit_url = document.querySelector( + `a[href^=${JSON.stringify(`/${repo}/commit`)}]` + )?.href; + if (!commit_url) return null; + const page_txt = await fetch(commit_url).then((v) => v.text()); + const page_xml = new DOMParser().parseFromString(page_txt, "text/html"); + return ( + [...page_xml.querySelectorAll('a[href*="id="]')] + .map((v) => { + const id = new URL( + v.getAttribute("href") ?? "https://example.com", + location.href + ).searchParams.get("id"); + return id; + }) + .find( + (v) => + !isNaN(Number(`0x${v}`)) && + !v.includes(".") && + // SHA1 repositories + (v.length === 40 || + // SHA256 repositories + v.length === 64) + ) ?? null + ); + }; + + // Check if in tree + if (/\/[^/]+\.git\/tree\/.*/iu.test(location.pathname)) { + // Check if viewing blob + if (document.querySelector(".content")?.textContent.includes("blob:")) { + // Ensure we're viewing blob + const blob = document + .querySelector(".content") + .textContent.match(/blob: ([0-9a-zA-Z]+)/)?.[1]; + if (blob && !document.querySelector('a[data-target="permalink"]')) { + (async () => { + const commit = await get_commit(); + if ( + commit && + !document.querySelector('a[data-target="permalink"]') && + !document.querySelector('a[data-target="unpermalink"]') + ) { + const is_permalink = + new URLSearchParams(location.search).get("id") !== commit; + // Add element + const a = document.createElement("a"); + const new_location = new URL(location.href); + if (is_permalink) new_location.searchParams.set("id", commit); + else new_location.searchParams.delete("id"); + a.href = `${new_location.pathname}${new_location.search}${new_location.hash}`; + a.textContent = is_permalink ? "permalink" : "latest"; + a.setAttribute( + "data-target", + (is_permalink ? "" : "un") + "permalink" + ); + document.querySelector('.content > a[href*="/plain/"]').outerHTML += + ", " + a.outerHTML; + } + })(); + } + } + } +} |