/* avatar injection: find author links, prepend the user's avatar. repo-root prefix is derived from the author link itself so this works under any URL prefix (repolist, CGI, ...). */ (function(){ function repoRootFrom(href){ var m = href.match(/^(.*)\/(timeline|forumpost|info)([?\/]|$)/); return m ? m[1] : ""; } function injectInto(link){ var m = link.href.match(/[?&]u=([^&"]+)/); if( !m ) return; if( link.parentNode.querySelector("img.avatar") ) return; var img = document.createElement("img"); img.className = "avatar"; img.alt = ""; img.src = repoRootFrom(link.getAttribute("href")) + "/uv/avatars/" + m[1] + ".png"; img.onerror = function(){ img.remove(); }; link.parentNode.insertBefore(img, link); } function scan(){ var sel = ".forumPostHdr a[href*='u='], .timelineModernDetail a[href*='u='], .timelineColumnarDetail a[href*='u=']"; document.querySelectorAll(sel).forEach(injectInto); } if( document.readyState === "loading" ){ document.addEventListener("DOMContentLoaded", scan); }else{ scan(); } })(); /* quick post: titleless microblogging on the forum list page. the thread title fossil requires is derived from the first line. */ (function(){ function root(){ return location.pathname.replace(/\/forum\/?$/, ""); } function deriveTitle(text){ var line = text.split("\n")[0].replace(/\s+/g, " ").trim(); if( line.length > 80 ) line = line.slice(0, 77) + "..."; return line; } function setup(){ if( !/cpage-forum\b/.test(document.body.className) ) return; var content = document.querySelector(".content"); if( !content ) return; var box = document.createElement("div"); box.className = "quickpost"; var ta = document.createElement("textarea"); ta.placeholder = "what's on your mind?"; var bar = document.createElement("div"); bar.className = "qp-bar"; var hint = document.createElement("span"); hint.className = "qp-hint"; hint.textContent = "no title needed — posts straight to the board"; var btn = document.createElement("input"); btn.type = "submit"; btn.value = "post"; bar.appendChild(hint); bar.appendChild(btn); box.appendChild(ta); box.appendChild(bar); var h = content.querySelector("h1, h2, .submenu"); content.insertBefore(box, h ? h.nextSibling : content.firstChild); btn.addEventListener("click", function(){ var text = ta.value.trim(); if( !text ) return; btn.disabled = true; fetch(root() + "/forumnew", { credentials: "same-origin" }) .then(function(r){ return r.text(); }) .then(function(page){ var m = page.match(/name="csrf" value="([^"]+)"/); if( !m ) throw new Error("no csrf"); var body = new URLSearchParams(); body.set("title", deriveTitle(text)); body.set("content", text); body.set("mimetype", "text/x-markdown"); body.set("csrf", m[1]); body.set("submit", "Submit"); return fetch(root() + "/forume1", { method: "POST", credentials: "same-origin", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: body.toString() }); }) .then(function(){ location.reload(); }) .catch(function(){ btn.disabled = false; }); }); } if( document.readyState === "loading" ){ document.addEventListener("DOMContentLoaded", setup); }else{ setup(); } })();