/* 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();
}
})();