// ==UserScript==
// @name        CVE Reference Links
// @author      Kees Cook
// @email       outflux.net | kees
// @version     1.0
// @namespace   http://outflux.net/greasemonkey
// @description Adds links to CVE References section
// @include     http://cve.mitre.org/cgi-bin/cvename.cgi*
// @include     https://cve.mitre.org/cgi-bin/cvename.cgi*
// @license     GNU General Public License
// ==/UserScript==

(function() {
  window.addEventListener("load", function(e) {

    function linkify(textnode,pattern,link) {
        var regex = new RegExp(pattern,'g');
        var span = document.createElement("span");
        var text = textnode.nodeValue;

        // only do the span replacement if we find text
        var spanned = 0;

        // for each text match, build text and links
        regex.lastIndex = 0;
        for (var match = null, lastLastIndex = 0;
             (match = regex.exec(text)); ) {
            if (!spanned) {
                // replace the nextnode with our new span
                textnode.parentNode.replaceChild(span, textnode); 
                spanned = 1;
            }


            // add the text to the right of the match
            span.appendChild(document.createTextNode(text.substring(lastLastIndex,match.index)));

            // figure out what to link to
            var url = link
            if (url == "") {
                url = match[0];
            }

            // attach the linkified-matching text
            var a = document.createElement("a");
            a.setAttribute("href",url);
            a.appendChild(document.createTextNode(match[0]));
            span.appendChild(a);
            
            lastLastIndex = regex.lastIndex;
        }

        if (spanned) {
            // attach any remaining text
            span.appendChild(document.createTextNode(text.substring(lastLastIndex)));
            // what does this do?
            span.normalize();
        }
    }

    // tags we will scan looking for un-hyperlinked urls
    var allowedParents = [
        "li"
//        "abbr", "acronym", "address", "applet", "b", "bdo", "big", "blockquote", "body", 
//        "caption", "center", "cite", "code", "dd", "del", "div", "dfn", "dt", "em", 
//        "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "i", "iframe",
//        "ins", "kdb", "li", "object", "pre", "p", "q", "samp", "small", "span", "strike", 
//        "s", "strong", "sub", "sup", "td", "th", "tt", "u", "var"
        ];
    nodes = document.evaluate(
        '//text()[parent::' + allowedParents.join(" or parent::") + ']',
        document,
        null,
        XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
        null);
    for (var i = 0; i < nodes.snapshotLength; i++) {
        linkify(nodes.snapshotItem(i), '(https?://.*)','');
    }
    //alert("Searched "+nodes.snapshotLength+" text nodes");
  }, false);
})();

