As some of you may know, Google Chrome has put some severe limitation on Greasemonkey scripts.
Chromium does not support
@require
,
There's a really easy way to get around including a full copy of jQuery for Chrome scripts when those scripts don't actually use any privileged features (GM_* functions, etc)...
Simply insert the script itself into the page DOM and execute! The best part is that this technique works just as well on Firefox+Greasemonkey, so you can use the same script for both:
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "(" + threadComments.toString() + ")(jQuery)";
document.body.appendChild(script);
function threadComments($) {
// taken from kip's http://userscripts-mirror.org/scripts/review/62163
var goodletters = Array('\u00c0','\u00c1','\u00c2','\u00c3','\u00c4','\u00c5','\u00c6','\u00c7'
,'\u00c8','\u00c9','\u00ca','\u00cb','\u00cc','\u00cd','\u00ce','\u00cf'
,'\u00d1','\u00d2','\u00d3','\u00d4','\u00d5','\u00d6'
,'\u00d8','\u00d9','\u00da','\u00db','\u00dc','\u00dd'
,'\u00e0','\u00e1','\u00e2','\u00e3','\u00e4','\u00e5','\u00e6','\u00e7'
,'\u00e8','\u00e9','\u00ea','\u00eb','\u00ec','\u00ed','\u00ee','\u00ef'
,'\u00f1','\u00f2','\u00f3','\u00f4','\u00f5','\u00f6'
,'\u00f8','\u00f9','\u00fa','\u00fb','\u00fc','\u00fd' ,'\u00ff').join('');
// from Benjamin Dumke's http://userscripts-mirror.org/scripts/review/68252
function goodify(s)
{
good = new RegExp("^[" + goodletters + "\\w]{3}");
bad = new RegExp("[^" + goodletters + "\\w]");
original = s;
while (s.length >3 && !s.match(good)) {
s = s.replace(bad, "");
}
if (!s.match(good))
{
// failed, so we might as well use the original
s = original;
}
return s;
}
in_reply_to = {};
function who(c, other_way) {
if (other_way)
{
// this is closer to the real @-reply heuristics
m = /@(\S+)/.exec(c);
}
else
{
m = /@([^ .:!?,()[\]{}]+)/.exec(c);
}
if (!m) {return}
if (other_way) {return goodify(m[1]).toLowerCase().slice(0,3);}
else {return m[1].toLowerCase().slice(0,3);}
}
function matcher(user, other_way) {
if (other_way)
{
return function () {
return goodify($(this).find(".comment-user").text()).toLowerCase().slice(0,3) == user
}
}
else
{
return function () {
return $(this).find(".comment-user").text().toLowerCase().slice(0,3) == user
}
}
}
function replyfilter(id) {
return function() {
return in_reply_to[$(this).attr("id")] == id;
}
}
function find_reference() {
comment_text = $(this).find(".comment-text").text();
if (who(comment_text))
{
fil = matcher(who(comment_text));
all = $(this).prevAll("tr.comment").filter(fil);
if (all.length == 0)
{
// no name matched, let's try harder
fil = matcher(who(comment_text, true), true);
all = $(this).prevAll("tr.comment").filter(fil);
if (all.length == 0) {return}
}
reference_id = all.eq(0).attr("id");
in_reply_to[$(this).attr("id")] = reference_id;
}
}
// How far may comments be indented?
// Note that MAX_NESTING = 3 means there are
// up to *four* levels (including top-level)
MAX_NESTING = 3
// How many pixels of indentation per level?
INDENT = 30
function indenter(parent) {
for (var i = MAX_NESTING; i > 0; i--)
{
if (parent.hasClass("threading-" + (i-1)) || (i == MAX_NESTING && parent.hasClass("threading-" + i)))
{
return function() {
$(this).addClass("threading-" + i).find(".comment-text").css({"padding-left": INDENT*i});
}
}
}
return function() {
$(this).addClass("threading-1").find(".comment-text").css({"padding-left": INDENT});
}
}
function do_threading(){
id = $(this).attr("id");
replies = $(this).nextAll("tr.comment").filter(replyfilter(id));
ind = indenter($(this));
replies.each(ind);
replies.insertAfter(this);
}
function go() {
$("tr.comment").each(find_reference);
$("tr.comment").each(do_threading);
}
$.ajaxSetup({complete: go});
go();
}
(unapologetically stolen from Shog9 on meta.stackoverflow since he didn't move it here, and I have to delete the meta post..)