FlightGear wiki:Instant-Refs: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(should be ready for use)
m (clear selection only if user doesn't hit "cancel")
Line 159: Line 159:
     if ( text != "" ) {
     if ( text != "" ) {
         var cquote = CreateCquote(text, parent);
         var cquote = CreateCquote(text, parent);
         window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote);
         if (window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote) != null)
        // FIXME: this breaks conventional copy/paste for whitelisted websites
            window.getSelection().removeAllRanges(); // deselect all text
        window.getSelection().removeAllRanges(); // deselect all text
     }
     }
}
}

Revision as of 22:06, 31 May 2014

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