FlightGear wiki:Instant-Refs

From FlightGear wiki
Revision as of 22:06, 31 May 2014 by Philosopher (talk | contribs) (clear selection only if user doesn't hit "cancel")
Jump to navigation Jump to search
or to any forum message
Note  For testing purposes, the alert showing the cleaned up fields are still enabled. You can comment it out in extractInfo().
// ==UserScript==
// @name       auto cquotes for sourceforge ml and forum
// @namespace  http://wiki.flightgear.org/
// @version    0.5
// @description automatically create proper wikimedia cquotes for sourceforge ml and forum text selections
// @match      http://sourceforge.net/p/flightgear/mailman/* 
// @match	   http://forum.flightgear.org/*
// @copyright  2013+, FlightGear.org
// ==/UserScript==


/* for each domain, fields: author, title, date, url.
 * for each field:
        xpath - relative to the text body element
        regex - will extract the first capture group (i.e. '(xxx)')
        prepend - a string to be prepended (useful for urls)
*/
var CONFIG = {
    "sourceforge.net": { 
        author: {
            xpath: "../../../tr/td/div/small/text()",
            regex: "/^From: (.*) <.*@.*>/"
        },
        title: {
            xpath: "../../../tr/td/div/div/b/a/text()"
        },
        date: {
            xpath: "../../../tr/td/div/small/text()",
            regex: "/ - (.*-.*-.*) /"
        },
        url: {
            xpath: "../../../tr/td/div/div/b/a/@href",
            prepend: "http://sourceforge.net"
        }
    },
    "forum.flightgear.org": {
        author: {
            xpath: "../p/strong/a/text()"
        },
        title: {
            xpath: "../h3/a/text()"
        },
        date: {
            xpath: "../p/text()[2]",
            regex: "/ » (.*),/"
        },
        url: {
            xpath: "../p/a/@href",
            regex: "/\.(.*)/",
            prepend: "http://forum.flightgear.org"
        }
    }
    
};

function getPathTo(element) {
    if (element.id!=='')
        return 'id("'+element.id+'")';
    if (element===document.body)
        return element.tagName;
    
    var ix= 0;
    var siblings= element.parentNode.childNodes;
    for (var i= 0; i<siblings.length; i++) {
        var sibling= siblings[i];
        if (sibling===element)
            return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
        if (sibling.nodeType===1 && sibling.tagName===element.tagName)
            ix++;
    }
}

function nowiki(text) {
    return "<nowiki>" + text + "</nowiki>";
}

function extractInfo(parentPath, profile) {
    var info = {};
    for (field in profile) {
        var fieldInfo = "";
        if (profile[field].xpath) {
            var fullPath =  parentPath + "/" + profile[field].xpath;
            fieldInfo = document.evaluate(fullPath, document, null, XPathResult.STRING_TYPE, null ).stringValue;
        }
        
        if (profile[field].regex) {
            var regex = eval(profile[field].regex); // to cleanup info
            fieldInfo = fieldInfo.match(regex)[1];
        }
        
        if (profile[field].prepend) {
            fieldInfo = "http://" + window.location.hostname + fieldInfo;
        }
        
        alert(field+" = "+fieldInfo);
        info[field] = fieldInfo;
    }
    
    return info;
}

// FIXME: remove extra \CR \LF (?)
function CreateCquote(text, parent) {
    var info = {};
    
    if(parent) {
        var profile = CONFIG[window.location.hostname];
        var parentPath = getPathTo(parent);
        
        info = extractInfo(parentPath, profile);
    } else {
        // fallback. XXX: not tested
        info.url = document.URL;
        info.title = "from " + window.location.hostname;
        info.author = "";
        info.date = "";
    }
    
    //TODO: add template string to profile
    var template = "{{cquote" + "\n" +
        "  |" + nowiki(text) + "\n" +
        "  |{{cite web |url=" + info.url + "\n" +
        "     |title=" + nowiki(info.title) + "\n" +
        "     |author=" + nowiki(info.author) + "\n" +
        "     |date=" + nowiki(info.date) + "\n" +
        "   }}" + "\n" +
        "}}";
    return template;
}

function GetSelectedText () {    
    var text = "";
    var parent = null;
    
    if (document.getSelection) {
        var sel = document.getSelection (); 
        parent = sel.anchorNode.parentNode;// anchorNode is the textnode, parentNode is the actual parent, i.e. html element
        text = sel;
    } else if (document.selection) { // for IE <= v8
        var textRange = document.selection.createRange ();
        parent = textRange.parentElement(); // XXX: not tested!
        text = textRange.text;
    }
        
    // check if we got text
    if ( text != "" ) {
        var cquote = CreateCquote(text, parent);
        if (window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote) != null)
            window.getSelection().removeAllRanges(); // deselect all text
    }
}

function register() {
    // check if we have a matching domain in the CONFIG hash
    if (CONFIG.hasOwnProperty(window.location.hostname) ) {        
        // if yes, register a callback to handle mouse events
        document.onmouseup = GetSelectedText;
    }        
}

window.addEventListener('load', register );