summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-01-15 16:24:16 +0100
committerLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-01-15 16:24:16 +0100
commit0730b5b45c4825f108d1c3f129c56061ecfd83c7 (patch)
tree8428da1a4188cd6f077daa1f0809b6e8d1ff2c9d
parentf7152ca7c85a39f678e709b3c54c453fc9a177f6 (diff)
downloadcgit-assets-0730b5b45c4825f108d1c3f129c56061ecfd83c7.tar.gz
cgit-assets-0730b5b45c4825f108d1c3f129c56061ecfd83c7.tar.bz2
cgit-assets-0730b5b45c4825f108d1c3f129c56061ecfd83c7.tar.lz
cgit-assets-0730b5b45c4825f108d1c3f129c56061ecfd83c7.zip

feat: permalinking

-rw-r--r--cgit.js74
1 files changed, 71 insertions, 3 deletions
diff --git a/cgit.js b/cgit.js
index 50470ab..99f818d 100644
--- a/cgit.js
+++ b/cgit.js
@@ -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;
+ }
+ })();
+ }
+ }
+ }
+}