2,733
edits
mNo edit summary |
Red Leader (talk | contribs) (date formatting + Chrome-specific box (more to come on that ;) )) |
||
Line 51: | Line 51: | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
// ==UserScript== | // ==UserScript== | ||
// @name | // @name Instant-Cquotes | ||
// @description | // @description Automatically converts mailing list and forum quotes into Mediawiki markup. | ||
// @namespace http://wiki.flightgear.org/ | // @namespace http://wiki.flightgear.org/ | ||
// @version 0. | // @version 0.12 | ||
// @icon http://wiki.flightgear.org/ | // @icon http://wiki.flightgear.org/images/6/62/FlightGear_logo.png | ||
// @require http://code.jquery.com/jquery-1.11.1.min.js | // @require http://code.jquery.com/jquery-1.11.1.min.js | ||
// @require https://code.jquery.com/ui/1.11.0/jquery-ui.min.js | // @require https://code.jquery.com/ui/1.11.0/jquery-ui.min.js | ||
Line 63: | Line 63: | ||
// @match http://sourceforge.net/p/flightgear/mailman/* | // @match http://sourceforge.net/p/flightgear/mailman/* | ||
// @match http://forum.flightgear.org/* | // @match http://forum.flightgear.org/* | ||
// @copyright 2013 | // @copyright 2013-2015, FlightGear.org (bigstones, Philosopher, Red Leader & Hooray) | ||
// ==/UserScript== | // ==/UserScript== | ||
Line 70: | Line 70: | ||
var debug = 0; | var debug = 0; | ||
/* content: | /* content: | ||
* - 'selection' supports only getSelectedText, will support getSelectedHtml | * - 'selection' supports only getSelectedText, will support getSelectedHtml | ||
Line 131: | Line 131: | ||
} | } | ||
}; | }; | ||
var OUTPUT = OutputMethods().msgbox; | var OUTPUT = OutputMethods().msgbox; | ||
function OutputMethods() { | function OutputMethods() { | ||
var methods = { | var methods = { | ||
popup: function(msg){ | |||
chrome.runtime.sendMessage({authen: "Instant-Cquotes", text: msg}); | |||
}, | |||
// shows a message box | // shows a message box | ||
msgbox: function(msg) { | msgbox: function(msg) { | ||
Line 141: | Line 145: | ||
window.getSelection().removeAllRanges(); // deselect all text | window.getSelection().removeAllRanges(); // deselect all text | ||
}, | }, | ||
// XXX: experimental | // XXX: experimental | ||
// show msg in a jQuery UI dialog | // show msg in a jQuery UI dialog | ||
jqueryDiag: function(msg) { | jqueryDiag: function(msg) { | ||
var diagDiv = $('<div id="MyDialog"><textarea id="quotedtext" rows="10" cols="80" readonly>' + msg + '</textarea></div>'); | var diagDiv = $('<div id="MyDialog"><textarea id="quotedtext" rows="10" cols="80" readonly>' + msg + '</textarea></div>'); | ||
var diagParam = { title: "Copy your quote with CTRL-C", | var diagParam = { title: "Copy your quote with CTRL-C", | ||
modal: true, | modal: true, | ||
Line 152: | Line 156: | ||
{ text: "Cancel", click: function () { $(this).dialog("close"); } }] | { text: "Cancel", click: function () { $(this).dialog("close"); } }] | ||
}; | }; | ||
diagDiv.dialog(diagParam); | diagDiv.dialog(diagParam); | ||
} | } | ||
}; | }; | ||
return methods; | return methods; | ||
}; | }; | ||
////////////////////// | ////////////////////// | ||
// TRANSFORM OPERATORS | // TRANSFORM OPERATORS | ||
// prepend 'prefix' | // prepend 'prefix' | ||
function prepend(prefix) { | function prepend(prefix) { | ||
Line 170: | Line 174: | ||
}; | }; | ||
} | } | ||
// extract the first capture group in the regex (i.e. '(xxx)') | // extract the first capture group in the regex (i.e. '(xxx)') | ||
function extract(regex) { | function extract(regex) { | ||
Line 177: | Line 181: | ||
}; | }; | ||
} | } | ||
// replaces newlines with "unescaped" <br/>'s | // replaces newlines with "unescaped" <br/>'s | ||
function newline2br() { | function newline2br() { | ||
Line 184: | Line 188: | ||
}; | }; | ||
} | } | ||
// remove html comments (e.g. '<!-- this is a comment -->') | // remove html comments (e.g. '<!-- this is a comment -->') | ||
function removeComments() { | function removeComments() { | ||
Line 191: | Line 195: | ||
}; | }; | ||
} | } | ||
// converts html <a>...</a>'s to wiki links, internal if possible | // converts html <a>...</a>'s to wiki links, internal if possible | ||
function a2wikilink() { | function a2wikilink() { | ||
Line 202: | Line 206: | ||
// links to the wiki with custom text (we preserve it) | // links to the wiki with custom text (we preserve it) | ||
html = html.replace(/<a[^(?:href)]*href="https?:\/\/wiki.flightgear.org\/(.*?)".*?>(.*?)<\/a>/g, "[[$1|$2]]"); | html = html.replace(/<a[^(?:href)]*href="https?:\/\/wiki.flightgear.org\/(.*?)".*?>(.*?)<\/a>/g, "[[$1|$2]]"); | ||
// then the others | // then the others | ||
html = html.replace(/<a[^(?:href)]*href="(.*?)".*?>(.*?)<\/a>/g, "[$1 $2]"); | html = html.replace(/<a[^(?:href)]*href="(.*?)".*?>(.*?)<\/a>/g, "[$1 $2]"); | ||
Line 208: | Line 212: | ||
}; | }; | ||
} | } | ||
// converts embedded html images to external links, | // converts embedded html images to external links, | ||
// but shows them as little images if they're from the wiki | // but shows them as little images if they're from the wiki | ||
Line 217: | Line 221: | ||
}; | }; | ||
} | } | ||
// puts newlines where it makes for more readable wiki "source" | // puts newlines where it makes for more readable wiki "source" | ||
function addNewlines() { | function addNewlines() { | ||
Line 226: | Line 230: | ||
} | } | ||
} | } | ||
// converts phpBB way of doing font style to the wiki way | // converts phpBB way of doing font style to the wiki way | ||
function phpBB_fontstyle2wikistyle() { | function phpBB_fontstyle2wikistyle() { | ||
Line 237: | Line 241: | ||
}; | }; | ||
} | } | ||
// converts (html) phpBB code blocks to wiki <syntaxhighlight> | // converts (html) phpBB code blocks to wiki <syntaxhighlight> | ||
// FIXME: not actually using the above tag, because the copied html has | // FIXME: not actually using the above tag, because the copied html has | ||
Line 244: | Line 248: | ||
function phpBB_code2syntaxhighlight() { | function phpBB_code2syntaxhighlight() { | ||
return function(bbhtml) { | return function(bbhtml) { | ||
return bbhtml.replace(/<dl.*?><dt>.*?<\/dt><dd><code>(.*?)<\/code><\/dd><\/dl>/g, "< | return bbhtml.replace(/<dl.*?><dt>.*?<\/dt><dd><code>(.*?)<\/code><\/dd><\/dl>/g, "<syntaxhighlight>\n$1\n</syntaxhighlight>"); | ||
}; | }; | ||
} | } | ||
// converts (html) phpBB quotes to simple wiki cquotes (author not cited, it'd get messy anyway) | // converts (html) phpBB quotes to simple wiki cquotes (author not cited, it'd get messy anyway) | ||
function phpBB_quote2cquote() { | function phpBB_quote2cquote() { | ||
Line 254: | Line 258: | ||
}; | }; | ||
} | } | ||
// converts smilies images from phpBB. | // converts smilies images from phpBB. | ||
// Must be used BEFORE img2link(), because it makes a broken link of them | // Must be used BEFORE img2link(), because it makes a broken link of them | ||
Line 262: | Line 266: | ||
} | } | ||
} | } | ||
// escapes pipe characters that can be problematic inside a template. | // escapes pipe characters that can be problematic inside a template. | ||
// Must be used BEFORE html tags were converted, or they get messed up. | // Must be used BEFORE html tags were converted, or they get messed up. | ||
Line 272: | Line 276: | ||
} | } | ||
} | } | ||
// escapes the equal sign that can be problematic inside a template. | // escapes the equal sign that can be problematic inside a template. | ||
// Must be used AFTER html tags were converted, or they get messed up. | // Must be used AFTER html tags were converted, or they get messed up. | ||
Line 280: | Line 284: | ||
} | } | ||
} | } | ||
/////////////////// | /////////////////// | ||
// SCRIPT MAIN BODY | // SCRIPT MAIN BODY | ||
window.addEventListener('load', register); | window.addEventListener('load', register); | ||
function register() { | function register() { | ||
// check if we have a matching domain in the CONFIG hash | // check if we have a matching domain in the CONFIG hash | ||
Line 293: | Line 297: | ||
} | } | ||
} | } | ||
// main function | // main function | ||
function instantCquote() { | function instantCquote() { | ||
if(getSelectedText() === "") return; | if(getSelectedText() === "") return; | ||
var profile = CONFIG[window.location.hostname]; | var profile = CONFIG[window.location.hostname]; | ||
var parent = getSelectionParent(); | var parent = getSelectionParent(); | ||
var info = parent ? extractInfo(profile, parent) : extractInfoFallback(); | var info = parent ? extractInfo(profile, parent) : extractInfoFallback(); | ||
if (info) { | if (info) { | ||
var cquote = createCquote(info); | var cquote = createCquote(info); | ||
Line 310: | Line 314: | ||
} | } | ||
} | } | ||
function extractInfoFallback() { // XXX untested | function extractInfoFallback() { // XXX untested | ||
var info = {}; | var info = {}; | ||
Line 320: | Line 324: | ||
return info; | return info; | ||
} | } | ||
function extractInfo(profile, parent) { | function extractInfo(profile, parent) { | ||
var info = {}; | var info = {}; | ||
for (var field in profile) { | for (var field in profile) { | ||
if (!profile.hasOwnProperty(field)) continue; | if (!profile.hasOwnProperty(field)) continue; | ||
// this part gets the data, both for field and content (i.e. text, html) | // this part gets the data, both for field and content (i.e. text, html) | ||
var fieldInfo = extractFieldInfo(profile, parent, field); | var fieldInfo = extractFieldInfo(profile, parent, field); | ||
if (debug) alert("pre trans:\n" + field + " = " + fieldInfo); | if (debug) alert("pre trans:\n" + field + " = " + fieldInfo); | ||
var transform = profile[field].transform; | var transform = profile[field].transform; | ||
if(transform) fieldInfo = applyTransformations(fieldInfo, transform); | if(transform) fieldInfo = applyTransformations(fieldInfo, transform); | ||
if (debug) alert("post trans:\n" + field + " = " + fieldInfo); | if (debug) alert("post trans:\n" + field + " = " + fieldInfo); | ||
info[field] = fieldInfo; | info[field] = fieldInfo; | ||
} | } | ||
return info; | return info; | ||
} | } | ||
function extractFieldInfo(profile, parent, field) { | function extractFieldInfo(profile, parent, field) { | ||
if (field != "content") { | if (field != "content") { | ||
Line 354: | Line 358: | ||
} | } | ||
} | } | ||
function applyTransformations(fieldInfo, trans) { | function applyTransformations(fieldInfo, trans) { | ||
if(typeof trans === "function") { | if(typeof trans === "function") { | ||
Line 375: | Line 379: | ||
" |title=" + nowiki(info.title) + "\n" + | " |title=" + nowiki(info.title) + "\n" + | ||
" |author=" + nowiki(info.author) + "\n" + | " |author=" + nowiki(info.author) + "\n" + | ||
" |date=" + | " |date=" + datef(info.date) + "\n" + | ||
" }}" + "\n" + | " }}" + "\n" + | ||
"}}"; | "}}"; | ||
return template; | return template; | ||
} | } | ||
function createForumQuote(info) { | function createForumQuote(info) { | ||
//TODO: add template string to profile | //TODO: add template string to profile | ||
Line 388: | Line 392: | ||
return template; | return template; | ||
} | } | ||
function nowiki(text) { | function nowiki(text) { | ||
return "<nowiki>" + text + "</nowiki>"; | return "<nowiki>" + text + "</nowiki>"; | ||
} | } | ||
//////////////////// | //////////////////// | ||
// UTILITY FUNCTIONS | // UTILITY FUNCTIONS | ||
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | |||
// Returns the correct ordinal adjective | |||
function ordAdj(date){ | |||
date = date.toString().substr(1); | |||
if(date == "1"){ | |||
return "st"; | |||
}else if(date == "2"){ | |||
return "nd"; | |||
}else if(date == "3"){ | |||
return "rd"; | |||
}else{ | |||
return "th"; | |||
} | |||
}; | |||
// Formats the date to this format: Apr 26th, 2015 | |||
function datef(text){ | |||
var date = new Date(text); | |||
return MONTHS[date.getMonth()] + " " + date.getDate() + ordAdj(date.getDate()) + ", " + date.getFullYear(); | |||
} | |||
// IE8 compat. function | // IE8 compat. function | ||
function getSelectionParent() { | function getSelectionParent() { | ||
Line 401: | Line 427: | ||
// anchorNode is the textnode, parentNode is the parent html element | // anchorNode is the textnode, parentNode is the parent html element | ||
return document.getSelection().anchorNode.parentNode; | return document.getSelection().anchorNode.parentNode; | ||
} else if (document.selection) { // for IE <= v8 - XXX: not tested! | } else if (document.selection) { // for IE <= v8 - XXX: not tested! | ||
return document.selection.createRange().parentElement(); | return document.selection.createRange().parentElement(); | ||
} | } | ||
} | } | ||
// IE8 compat. function | // IE8 compat. function | ||
function getSelectedText() { | function getSelectedText() { | ||
if(document.getSelection) { // for modern, standard compliant browsers | if(document.getSelection) { // for modern, standard compliant browsers | ||
return document.getSelection().toString(); | return document.getSelection().toString(); | ||
} else if (document.selection) { // for IE <= v8 - XXX: not tested! | } else if (document.selection) { // for IE <= v8 - XXX: not tested! | ||
return document.selection.createRange().text; | return document.selection.createRange().text; | ||
} | } | ||
} | } | ||
// IE8 compat. function (copied from http://stackoverflow.com/a/6668159 ) | // IE8 compat. function (copied from http://stackoverflow.com/a/6668159 ) | ||
function getSelectedHtml() { | function getSelectedHtml() { | ||
Line 436: | Line 462: | ||
return html; | return html; | ||
} | } | ||
// copied from http://stackoverflow.com/a/2631931 | // copied from http://stackoverflow.com/a/2631931 | ||
function getXPathTo(element) { | function getXPathTo(element) { | ||
Line 443: | Line 469: | ||
if (element === document.body) | if (element === document.body) | ||
return element.tagName; | return element.tagName; | ||
var ix= 0; | var ix= 0; | ||
var siblings = element.parentNode.childNodes; | var siblings = element.parentNode.childNodes; | ||
Line 454: | Line 480: | ||
} | } | ||
} | } | ||
// copied from http://stackoverflow.com/a/12034334 | // copied from http://stackoverflow.com/a/12034334 | ||
var entityMap = { | var entityMap = { | ||
Line 465: | Line 491: | ||
"\n": "<br/>" | "\n": "<br/>" | ||
}; | }; | ||
function escapeHtml(string) { | function escapeHtml(string) { | ||
return String(string).replace(/[&<>"'\/]|[\n]/g, function (s) { | return String(string).replace(/[&<>"'\/]|[\n]/g, function (s) { | ||
return entityMap[s]; | return entityMap[s]; | ||
}); | }); | ||
}</syntaxhighlight> | } | ||
</syntaxhighlight> | |||
[[Category:Wiki maintenance]] | [[Category:Wiki maintenance]] |