I don't know about anybody else, but every now and then I would like to completely ignore the existence of a particular thread. Well, I now have a way! I have written (well, I've ripped-off somebody else's code and hacked it about to do what I want) a Greasemonkey script that will hide a thread from both the "New Posts" view and the normal forum view with a single click. At the moment, it won't hide a thread on the front page of the forum though.
Oh, I think it will work on the search results too... But I haven't tried it yet.
This gets a bit technical, so bear with me...
Firstly, you'll need the Greasemonkey add-on for FireFox 3. Got it? Good.
Now, open Tools > Greasemonkey > New User Script...
Give it a name (say "BCUK KillFile"), a namespace (doesn't really matter what it is - "http://foo" should do OK), and a description.
Under "Includes (One per line)" enter: "http://www.bushcraftuk.com/forum/*"
Hit OK.
If you've used Greasemonkey before, it will now open your text editor. If you haven't, you'll need to set one - I suggest c:\windows\notepad.exe for convenience. (Assuming you're on Windows. If you're not, you probably don't need me to tell you what to do here.)
Then simply paste in the code below, and save it. From now on, whenever you view the "New Posts" list, or an individual forum, each thread title will have an [ignore] link next to it. Simply hit that to banish the thread (OK, you'll need to refresh the page first). You will also have an "Ignored Threads" option up in the menu bar (next to New Posts, Search, Log Out) - hit that to open a little window where you can see all the threads you're ignoring, remove a thread from the ignore list, or clear the list entirely.
I haven't tested this very thoroughly, and I have no real intention of supporting it properly, but I'm prepared to try and answer questions if need be. However, if it breaks your computer, it's your own lookout. I take no responsibility, express or implied, for anything at all.
So, here's the code:
[With thanks to whoever ripped off the code that I'm ripping off. I believe it originates with Damian Penney and Tim & Jeff Ur, who wrote the Google Groups KillFile. I dunno how many hands it's been through since. Sorry guys, but that's the internet for you. ]
Oh, I think it will work on the search results too... But I haven't tried it yet.
This gets a bit technical, so bear with me...
Firstly, you'll need the Greasemonkey add-on for FireFox 3. Got it? Good.
Now, open Tools > Greasemonkey > New User Script...
Give it a name (say "BCUK KillFile"), a namespace (doesn't really matter what it is - "http://foo" should do OK), and a description.
Under "Includes (One per line)" enter: "http://www.bushcraftuk.com/forum/*"
Hit OK.
If you've used Greasemonkey before, it will now open your text editor. If you haven't, you'll need to set one - I suggest c:\windows\notepad.exe for convenience. (Assuming you're on Windows. If you're not, you probably don't need me to tell you what to do here.)
Then simply paste in the code below, and save it. From now on, whenever you view the "New Posts" list, or an individual forum, each thread title will have an [ignore] link next to it. Simply hit that to banish the thread (OK, you'll need to refresh the page first). You will also have an "Ignored Threads" option up in the menu bar (next to New Posts, Search, Log Out) - hit that to open a little window where you can see all the threads you're ignoring, remove a thread from the ignore list, or clear the list entirely.
I haven't tested this very thoroughly, and I have no real intention of supporting it properly, but I'm prepared to try and answer questions if need be. However, if it breaks your computer, it's your own lookout. I take no responsibility, express or implied, for anything at all.
So, here's the code:
Code:
// ==UserScript==
// @name vBulletin Kill Thread
// @namespace http://killthread.gregorach.com/
// @description Kill threads in vBulletin
// @include http://www.bushcraftuk.com/forum/*
// ==/UserScript==
/*===================================================================================*\
| For vBulletin ??? |
| 2008 By Gregorach |
| Ripped off from soemthing ripped off from Google Groups Killfile v3.5.1 |
| 2008 by Damian Penney, Tim & Jeff Ur |
\*===================================================================================*/
// Start
var showing = false;
unsafeWindow.closeThreadthreadKillList = function() {
var killDiv = document.getElementById("threadKillList");
killDiv.style.visibility = "hidden";
}
unsafeWindow._ThreadReanimate = function(killspec) {
window.setTimeout(Reanimate, 0, killspec);
}
unsafeWindow._ThreadKillFile_Set = function(killspec, title) {
killspec = killspec.replace(/^\s+|\s+$/g, "");
window.setTimeout(SetKillFile, 0, killspec, title);
}
unsafeWindow._Purge = function() {
window.setTimeout(updateKillFile, 0, Array(), new Array());
alert("KillFile Purged.\nRefresh page to see changes.");
}
function JavaScriptEscape(text) {
if (!arguments.callee.sRE) {
var specials = [
'"', '\'', '\\'
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('|\\') + ')', 'g'
);
}
return escape(text.replace(arguments.callee.sRE, '\\$1'));
}
function QuoteEscape(text) {
if (!arguments.callee.sRE) {
var specials = [
'\''
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('|\\') + ')', 'g'
);
}
return escape(text.replace(arguments.callee.sRE, '\\$1'));
}
function RegExpEscape(text) {
if (!arguments.callee.sRE) {
var specials = [
'/', '.', '*', '+', '?', '|',
'(', ')', '[', ']', '{', '}', '\\'
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('|\\') + ')', 'g'
);
}
return text.replace(arguments.callee.sRE, '\\$1');
}
function Reanimate(killspec) {
var splitCh = String.fromCharCode(255);
var data = "";
var titleData = "";
var list = new Array();
var titleList = new Array();
var newList = new Array();
var newTitleList = new Array();
var title = "";
// initialize variables
data = unescape(GM_getValue("ThreadKillFile", "-----"));
list = data.split(splitCh);
titleData = unescape(GM_getValue("ThreadTitleKillFile", "-----"));
titleList = titleData.split(splitCh);
for (var j = 0; j < list.length; j++) {
if (list[j] != killspec) {
newList.push(list[j]);
newTitleList.push(titleList[j]);
} else {
title = titleList[j];
}
}
updateKillFile(newList, newTitleList);
alert('"' + title + '" has been removed from the KillFile.\nRefresh page to see changes.');
}
function SetKillFile(killspec, title) {
var splitCh = String.fromCharCode(255);
var data = "";
var titleData = "";
var list = new Array();
var titleList = new Array();
// initialize variables
data = unescape(GM_getValue("ThreadKillFile", "-----"));
list = data.split(splitCh);
list.push(RegExpEscape(killspec));
titleData = unescape(GM_getValue("ThreadTitleKillFile", "-----"));
titleList = titleData.split(splitCh);
titleList.push(title);
updateKillFile(list, titleList);
try {
var targetLink = document.getElementById("thread_title_" + killspec);
var wrappingTable = document.evaluate("ancestor::tr", targetLink, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
GM_log("stripping comment from thread view");
var pNode = wrappingTable.snapshotItem(0);
pNode.parentNode.removeChild(pNode);
alert('"' + title + '" has been added to the KillFile.');
} catch (ex) {
alert('"' + title + '" has been added to the KillFile.\nRefresh page to see changes.');
}
}
unsafeWindow.ManageThreadKillFile = function() {
var killDiv = document.getElementById("threadKillList");
if (showing == false) {
killDiv.style.visibility = "visible";
showing = true;
} else {
killDiv.style.visibility = "hidden";
showing = false;
}
}
function GroupsBeta_Thread_List_View(list) {
// Delete comments in thread comment view
var threads = document.getElementById('threadslist');
if (!threads) return;
var candidates = document.evaluate(".//td[3]/div/a", threads, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var blocked = false;
var threadLinkRE = new RegExp("showthread\.php.t=([0-9]+)")
if (candidates.snapshotLength > 0) {
for (var i = 0; i < candidates.snapshotLength; i++) {
var cand = candidates.snapshotItem(i);
if (threadLinkRE.test(cand.getAttribute("href"))) {
var threadId = threadLinkRE.exec(cand.getAttribute("href"))[1];
var title = cand.textContent;
blocked = false;
for (var j = 0; !blocked && j < list.length; j++) {
if (threadId == list[j]) {
wrappingTable = document.evaluate("ancestor::tr", cand, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
GM_log("stripping comment from thread view");
var pNode = wrappingTable.snapshotItem(0);
pNode.parentNode.removeChild(pNode);
blocked = true;
}
}
if (!blocked) {
var spacer = document.createTextNode(" ");
var link = document.createElement("a");
link.href = "javascript:_ThreadKillFile_Set('" + threadId + "', '" + QuoteEscape(title) + "');";
cand.parentNode.appendChild(spacer);
link.appendChild(document.createTextNode("[Ignore]"));
cand.parentNode.appendChild(link);
blocked = false;
}
}
}
}
}
function updateKillFile(list, titleList) {
var splitCh = String.fromCharCode(255);
data = list.join(splitCh);
window.setTimeout(GM_setValue, 0, "ThreadKillFile", escape(data));
titleData = titleList.join(splitCh);
window.setTimeout(GM_setValue, 0, "ThreadTitleKillFile", escape(titleData));
updateKillFileText(list, titleList);
}
function updateKillFileText(list, titleList) {
var newDiv = document.getElementById("threadKillList");
var divHtml = "<b>Ignored Thread List</b>";
divHtml = divHtml + "<span style='float:right'><a href=\"javascript:closeThreadthreadKillList ();\">CLOSE</a></span>";
divHtml += '<br/><br/>';
divHtml += "X - remove from list<br/>"
for (var j = 1; j < list.length; j++) {
divHtml += "<a href=\"javascript:_ThreadReanimate('" + JavaScriptEscape(list[j]) + "');\">X</a> "
+ titleList[j] + "<br/>";
}
divHtml += "<br/><br/><a href=\"javascript:_Purge()\">Purge List</a>"
+ "<br/><br/><center><font size=0.5em>Brought to you by gregorach</font></center>"
newDiv.innerHTML = divHtml;
//document.getElementById('deleteOP').checked = GM_getValue('ThreadIgnoreListOptions', false);
}
function GroupsBeta_Run() {
// Add the kill file menu option to the menu bar
var splitCh = String.fromCharCode(255);
var list = new Array();
data = unescape(GM_getValue("ThreadKillFile", "-----"));
list = data.split(splitCh);
// get thread title list
var titleList = new Array();
titleData = unescape(GM_getValue("ThreadTitleKillFile", "-----"));
titleData = titleData.split(splitCh);
var titleView = false;
// Determine what view mode we are in
var candidates = document.evaluate("//DIV[@class='maincontboxhead']//td[2]//span//b", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < candidates.snapshotLength; i++) {
var cand = candidates.snapshotItem(i);
if (cand.textContent.indexOf("Topic list") >= 0) {
titleView = true;
}
}
var cand = document.getElementById('navbar_search');
var candParent = cand.parentNode;
//if (linkText.indexOf("Help") >= 0) {
var newLink = document.createElement('a');
newLink.setAttribute('href', 'javascript:ManageThreadKillFile()');
var pipe = document.createTextNode(" | ");
var linkText = document.createTextNode("Ignored Threads");
var tdata = document.createElement('td');
tdata.className = 'vbmenu_control';
candParent.appendChild(tdata);
tdata.appendChild(newLink);
newLink.appendChild(linkText);
// Creat the div that will show all the folks on the killfile
var newDiv = document.createElement("div");
newDiv.id = "allfolks";
var divHtml = "The Morgue";
newDiv.innerHTML = divHtml;
cand.parentNode.insertBefore(newDiv, cand.nextSibling);
newDiv.style.position = "absolute";
newDiv.style.top = "10px";
newDiv.style.left = "10px";
newDiv.style.backgroundColor = "#fff";
newDiv.style.fontSize = "12px";
newDiv.style.fontFamily = "Verdana";
newDiv.style.padding = "10px";
newDiv.style.border = "solid 1px #000000";
newDiv.style.visibility = "hidden";
newDiv.id = "threadKillList";
newDiv.style.zIndex = "300";
newDiv.style.textAlign = 'left';
updateKillFileText(list, titleData);
GroupsBeta_Thread_List_View(list);
}
// Main routine
GM_log(location.href);
GroupsBeta_Run();
// End
[With thanks to whoever ripped off the code that I'm ripping off. I believe it originates with Damian Penney and Tim & Jeff Ur, who wrote the Google Groups KillFile. I dunno how many hands it's been through since. Sorry guys, but that's the internet for you. ]