11

Inspired by this MSO question.

This tiny userscript will add a link to the timeline for any post, just below the "favorite question" star button.

Example image:

timeline button example

This is the code:

// ==UserScript==
// @name        Add Timeline Button
// @namespace   none
// @description Adds a "View Timeline" Button to StackOverflow
// @match       http://*.askubuntu.com/questions/*
// @match       http://*.onstartups.com/questions/*
// @match       http://*.serverfault.com/questions/*
// @match       http://*.stackapps.com/questions/*
// @match       http://*.stackexchange.com/questions/*
// @match       http://*.stackoverflow.com/questions/*
// @match       http://*.superuser.com/questions/*
// @author      csharpler
// @version     0.2
// ==/UserScript==

/*
 * Version History
 *      * 0.1 (2013-06-11): First release
 *      * 0.2 (2013-06-12): * changed includes
 *                          * improved regex
 *                          - removed unsafeWindow, replaced with function wrapper
 */

withPages_jQuery(run);

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);
};

function run(){
    var uri = location.href;
    var post = location.pathname.match(/questions\/(\d+)\D/i);
    var newuri = "";
    if(post && post.length > 1){
        newuri = location.protocol + "//" + location.host + "/posts/" + post[1] + "/timeline";
    }
    $(".favoritecount").after("<a href='" + newuri + "'>View Timeline</a>");
}

Feel free to submit any bugs, feature requests and comments on the script.

This script was tested with the following settings:

  • Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:20.0) Gecko/20130520 Firefox/20.0 PaleMoon/20.1-x64
  • SO and MSO pages, other SE pages will probably work (please tell me if they don't!)
  • Greasemonkey 1.9
11

Good idea. There's a few minor niggles, though:

  1. Don't use unsafeWindow, this will break in Chrome and will not even work in Firefox+Greasemonkey if the effective @grant changes.

  2. 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/*
    
  3. The regex match needs to be more robust, to account for all legal characters in the URL, and for anchors.

  4. 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 button: Install from GitHub Gist


Change log:

Versn  Date        Change
-----  ----------  --------------------------------------------------------------------------
1.5    2019-08-28  Updated Metadata and Lint config for Tampermonkey changes and performance.
1.4    2019-08-28  SE renamed `short-link` to `js-share-link`.
1.3    2016-08-19  SE changed Timelines. Answers were separated out from the question timeline.
1.2    2015-07-22  Updated match list.
1.1    2014-02-07  Added revisions link. (On private copy, didn't update Gist until 2015.)
1.0    2013-06-11  Initial release to the public.
  • Old comments moved to chat. – Brock Adams Nov 7 '18 at 6:15
  • I noticed this seems to have stopped working so I posted a small tweak as a new answer, but then noticed you have a gist with the download link. I wasn't sure what the best way was to handle it - maybe you'd be best to update your gist with the change and just delete my answer once done assuming it looks OK to you? – PeterJ Aug 28 at 11:42
  • Thanks, @PeterJ. It looks like they changed the markup in the last day or so. Updated the script and will try to remember to move it to GitHub proper on some future rainy day... – Brock Adams Aug 28 at 15:14
2

I noticed recently that this stopped working and the CSS class short-link needed changing to js-share-link, here's an update:

// ==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.4
// @history     1.4 CSS class short-link needed changing to js-share-link
// @history     1.3 SE changed Timelines. Answers were separated out from the question timeline.
// @history     1.2 Updated match list
// @history     1.1 Added revisions link
// @grant       none
// ==/UserScript==

$(".post-menu").each ( function (J) {
    var jThis   = $(this);
    var href    = jThis.find ('a[class="js-share-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>'
        );
        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>');
} );

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .