There are 2 previous versions of this script.
// HowlsOfOutrage.user.js
//
// Copyright 2010-2011, Michael Devore
// This file is licensed under the terms of the Artistic License 2.0.
// See http://www.opensource.org/licenses/artistic-license-2.0.php for the license itself.
//
// This is a Greasemonkey script.
// See http://www.greasespot.net/ for more information on Greasemonkey.
//
// ==UserScript==
// @name HowlsOfOutrage
// @namespace http://www.devoresoftware.com/gm/hoo
// @description show MetaFilter favoriters (favoritors?) on hover
// @include http://*.metafilter.com/*
// ==/UserScript==
//
// version 2: adds explicit text color for white background, variable-height box,
// hover over post favorites for list in addition to existing comment support
// version 3: adds loading message for when response is slow,
// minimum delay between favorites popup displays, cosmetic stuff
var favPopUp;
var favWork;
var mfBackgroundColor = "#006699"; // MetaFilter blue as background color
var favLoadDelay = 1; // minimum seconds between subsequent displays of favorite lists
var waitForDelay = false;
var waitForHover = false;
var currentEvent;
function howlMain()
{
favWork = document.createElement("div");
favPopUp = document.createElement("div");
favPopUp.style.width = "300";
favPopUp.style.height = "auto";
// favPopUp.style.height = "192";
favPopUp.style.top = "0px";
favPopUp.style.left = "0px";
favPopUp.style.overflow = "hidden";
favPopUp.style.color = "white";
favPopUp.style.paddingLeft = "2px";
favPopUp.style.fontSize = "10pt";
favPopUp.style.backgroundColor = mfBackgroundColor;
favPopUp.style.borderStyle = "dashed";
favPopUp.style.borderWidth = "1px";
favPopUp.style.borderColor = "black";
favPopUp.style.position = "absolute";
favPopUp.style.display = "none";
favPopUp.style.opacity = ".94";
document.getElementsByTagName('body')[0].appendChild(favPopUp);
var xpath = "//DIV/SPAN[starts-with(text(),'posted by') and @class='smallcopy']/SPAN[starts-with(@id,'fav')]/SPAN[starts-with(@id,'favcnt')]/A";
var postNodes = document.evaluate(
xpath,
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
var totalFavAnchors = postNodes.snapshotLength;
for (var i = 0; i < totalFavAnchors; i++)
{
var favNode = postNodes.snapshotItem(i);
var hrefValue = favNode.getAttribute('href');
favNode.addEventListener('mouseover', checkFavHover, false);
favNode.addEventListener('mouseout', favGoAway, false);
}
// pick up post favorites
xpath = "//DIV[@class='copy']/SPAN[starts-with(text(),'posted by') and @class='smallcopy']/SPAN[starts-with(@id,'favcnt')]/A";
postNodes = document.evaluate(
xpath,
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
if (postNodes.snapshotLength)
{
var favNode = postNodes.snapshotItem(0);
var hrefValue = favNode.getAttribute('href');
favNode.addEventListener('mouseover', checkFavHover, false);
favNode.addEventListener('mouseout', favGoAway, false);
}
}
function favGoAway(evt)
{
waitForHover = false;
favPopUp.style.display = "none";
}
function checkFavHover(evt)
{
currentEvent = evt;
if (waitForDelay)
{
waitForHover = true;
return;
}
waitForHover = false;
favHover(evt);
}
function timesUp()
{
waitForDelay = false;
if (waitForHover)
{
waitForHover = false;
favHover(currentEvent);
}
}
function favHover(evt)
{
waitForDelay = true;
window.setTimeout(timesUp, favLoadDelay * 1000);
// favPopUp.innerHTML = "";
favPopUp.style.backgroundColor = "red";
favPopUp.innerHTML = " ...loading...";
favPopUp.style.top = evt.pageY - 4;
favPopUp.style.left = evt.pageX + 16;
favPopUp.style.display = "";
var favURL = evt['target']['href'];
evt['target']['title'] = "";
// cross-domain request, have to use GM_xmlhttpRequest()
GM_xmlhttpRequest(
{
method : "GET",
url : favURL,
headers :
{
"User-Agent" : "Mozilla/5.0",
"Accept" : "text/xml"
},
onload:function(response)
{
processFav(response.responseText);
}
});
}
function processFav(pText)
{
favWork.innerHTML = pText;
var xpath = "/DIV[@class='copy']/A";
var userNodes = document.evaluate(
xpath,
favWork,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
var totalUserAnchors = userNodes.snapshotLength;
favPopUp.innerHTML = "";
favPopUp.style.backgroundColor = mfBackgroundColor;
for (var i = 0; i < totalUserAnchors; i++)
{
var currentNode = userNodes.snapshotItem(i);
var aNode = currentNode.cloneNode(true);
aNode.style.color = "white";
if (i)
{
favPopUp.appendChild(document.createTextNode(", "));
}
favPopUp.appendChild(aNode);
}
}
howlMain();