FlightGear wiki:Instant-Refs: Difference between revisions
Jump to navigation
Jump to search
(should be ready for use) |
Philosopher (talk | contribs) 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) | ||
window.getSelection().removeAllRanges(); // deselect all text | |||
} | } | ||
} | } |
Revision as of 22:06, 31 May 2014
- A simple userscript extension implemented in JavaScript
- Supported by FireFox, Chrome, Chromium, probably Opera and others
- in case of doubt, just install the GreaseMonkey/TamperMonkey extension
- install the script
- go to some sourceforge.net mail archive URL, for example: http://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/5389094A.3080601%40gmail.com/#msg32400727
- or to any forum message
- copy/mark some relevant portion of text
- and directly get a full cquote paragraph that you can add to the wiki here
- stop whining that proper cquotes are too painful :-)
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 );