Good idea. There's a few minor niggles, though:
Don't use
unsafeWindow
, this will break in Chrome and will not even work in Firefox+Greasemonkey if the effective@grant
changes.Avoid leading
*
wildcards in@includes
, if you can help it. This is a big performance hit.@match
limits the wildcard scope and performs much better and reports the sites/security correctly on Chrome. This gets all current SE sites:// @match *://*.askubuntu.com/questions/* // @match *://*.onstartups.com/questions/* // @match *://*.serverfault.com/questions/* // @match *://*.stackapps.com/questions/* // @match *://*.stackexchange.com/questions/* // @match *://*.stackoverflow.com/questions/* // @match *://*.superuser.com/questions/*
The regex
match
needs to be more robust, to account for all legal characters in the URL, and for anchors.Use injection so that the script will work on most userscript-capable browsers (Chrome, Firefox, Opera, Safari, etc.).
Here's a variant of the script I've been using. It also adds a "revisions" link since a post's history is sometimes hidden. It works on Chrome and Firefox, and should work on most other userscript-capable browsers:
View the source at GitHub Gist.
Install from GitHub Gist
// ==UserScript==
// @name Stack Exchange: Add Timeline and Revisions links to posts
// @description Adds links to posts to always show history and links to questions to show the Timeline".
// @namespace StackExchange
// @match *://*.askubuntu.com/questions/*
// @match *://*.mathoverflow.net/questions/*
// @match *://*.serverfault.com/questions/*
// @match *://*.stackapps.com/questions/*
// @match *://*.stackexchange.com/questions/*
// @match *://*.stackoverflow.com/questions/*
// @match *://*.superuser.com/questions/*
// @version 1.2
// @history 1.2 Updated match list
// @history 1.1 Added revisions link
// ==/UserScript==
function addUtilityLinks ($) {
$(".post-menu").each ( function (J) {
var jThis = $(this);
var href = jThis.find ('a[class="short-link"]').attr ("href");
var idMtch = href.split (/[qa]\/(\d+)/);
if (idMtch.length > 2) {
var id = idMtch[1];
jThis.append (
'<span class="lsep">|</span><a href="/posts/' + id + '/revisions">revisions</a>'
);
if (J === 0) { //-- Question only
jThis.append (
'<span class="lsep">|</span><a href="/posts/' + id + '/timeline">timeline</a>'
);
}
}
} );
$(".revcell3.vm>div").each (function () {
//-- Looks like a timebomb...
guid = $(this).find ("a").attr ("href").match (/\w{8} (?:-\w{4} ){3}-\w{12}/)[0];
$(this).prepend ('<a href="#rev' + guid + '">link</a><span class="lsep">|</span>');
} );
}
withPages_jQuery (addUtilityLinks);
function withPages_jQuery (NAMED_FunctionToRun) {
//--- Use named functions for clarity and debugging...
var funcText = NAMED_FunctionToRun.toString ();
var funcName = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1");
var script = document.createElement ("script");
script.textContent = funcText + "\n\n";
script.textContent += 'jQuery(document).ready( function () {' + funcName + '(jQuery);} );';
document.body.appendChild (script);
};