Source for "Joel on Software forum preview"

By Einar Egilsson
Has 1 other script.


// Joel on Software forum preview
// version 0.2
// 2007-04-12
//
// ==UserScript==
//
// @name            Joel on Software forum preview
// @namespace       http://tech.einaregilsson.com/download/jospreview.user.js
// @description     Shows a preview of a post that the mouse is hovering over.
// @author          Einar Egilsson (greasemonkey@einaregilsson.com)
// @include         http://discuss.joelonsoftware.com/*
// @include         http://discuss.techinterview.org/*
// @include         http://support.fogcreek.com/*
// @include         http://crazyontap.com/*
// @include         http://www.crazyontap.com/*
//
// @exclude         http://crazyontap.com*=*
// @exclude         http://www.crazyontap.com*=*
// @exclude         http://discuss.joelonsoftware.com/*.*.*
// @exclude         http://discuss.techinterview.org/*.*.*
// @exclude         http://support.fogcreek.com/*.*.*
//
// ==/UserScript==
/* BEGIN LICENSE BLOCK
Copyright (C) 2006 Einar Egilsson

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at
http://diveintomark.org/projects/greasemonkey/COPYING
or get a free printed copy by writing to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
END LICENSE BLOCK */


(function() {

    function log(str) {
        //Uncomment for debugging
        //GM_log(str);
    }

    function setPos(x, y) {
        if (window.previewNode) {
            var style = window.previewNode.getAttribute("style");
            style = style.replace(/top:\s*\d*/, "top: " + (y + 20)).replace(/left:\s*\d*/, "left: " + x);
            window.previewNode.setAttribute("style", style);
        }
    }

    function getPost(event) {

        var linkUrl = event.target.toString();
        var link = event.target;
        var post = linkUrl.split("?")[1];

        var text;
        window.currentPreviewUrl = linkUrl;

        for (var x = 0, y = 0;  link.offsetParent; link = link.offsetParent) {
            x += link.offsetLeft;
            y += link.offsetTop;
        }

        if (text = window.previewCache[linkUrl]) {
            log("Cache hit for " + linkUrl);
            setPos(x, y);
            window.previewNode.innerHTML = text;
            window.previewNode.style.display = "";
            window.currentPreviewUrl = linkUrl;

        } else {
            log("Cache miss for " + post);

            //Only get pages if the mouse is over them for more than 0.5 seconds.
            setTimeout(function() {

                if (window.currentPreviewUrl != linkUrl) {
                    log("Mouseout has fired for " + post + ", don't get page");
                    return;
                }
                GM_xmlhttpRequest({
                    method : "GET",
                    url : linkUrl,
                    headers: { "User-agent": "Mozilla/4.0 (compatible) Greasemonkey" },

                    onload: function(responseDetails) {

                        if (responseDetails.status != 200) {
                            alert("Failed to load preview, message is: " + responseDetails.status + " " + responseDetails.statusText);
                            return;
                        }

                        var src = responseDetails.responseText;
                        var start, end;

                        if (/crazyontap/.test(linkUrl)) {
                            start = src.indexOf('<div class="post">') + 18;
                        } else {
                            start = src.indexOf('<div class="discussBody">') + 25;
                        }
                        end = src.indexOf('</div>', start);


                        var text = src.substr(start, end - start);

                        window.previewCache[linkUrl] = text;

                        //Only show if the mouseout event hasn't fired
                        if (window.currentPreviewUrl == linkUrl) {
                            setPos(x, y);
                            window.previewNode.innerHTML = text;
                            window.previewNode.style.display = "";
                        } else {
                            log("Skipping set text for " + post + ", mouseout has fired");
                        }
                    }
                }); //end GM_xmlhttpRequest

            }, 500); //end setTimeout
        }

    }

    function clearPost(event) {
        window.previewNode.style.display = "none";
        window.currentPreviewUrl = "";
    }

    var link, links;

    links = document.getElementsByTagName("a");

    for (var i in links) {

        link = links[i];

        if (link.href &&
            (link.href.match(/discuss\.joelonsoftware\.com\/default\.asp\?\w+\.\d+\.\d+\.\d+$/)
             || link.href.match(/support\.fogcreek\.com\/default\.asp\?\w+\.\d+\.\d+\.\d+$/)
             || link.href.match(/discuss\.techinterview\.org\/default\.asp\?\w+\.\d+\.\d+\.\d+$/)
             || /topic\.php/.test(link.href))) {

            link.addEventListener("mouseover", getPost, true);
            link.addEventListener("mouseout", clearPost, true);
            link.title = "";
        }
    }

    window.previewCache = {};
    window.currentPreviewUrl = "";
    window.previewNode = document.createElement("div");

    window.previewNode.setAttribute("style",
                                      "position:absolute; \
                                       left: 20px; \
                                       top: 150px; \
                                       background-color:#ddd; \
                                       border:solid 1px black; \
                                       padding:3px; \
                                       color:black; \
                                       width:500px; \
                                       font-family:Arial, sans-serif; \
                                       font-size:12px; \
                                       display:none;");

    document.getElementsByTagName("body")[0].appendChild(window.previewNode);

    //alert('loaded');

})();



//Version history

// Version 0.2 -  2007-04-12
// Improved version. Now supports discuss.joelonsoftware.com, support.fogcreek.com,
// discuss.techinterview.com, and crazyontap.com which came from the old ?off discussion
// group that used to be at joels place.

// Version 0.1 -  2006-12-11
// Initial version. Only supports discuss.joelonsoftware.com