/* This script can be used to encode/decode text with ]. Just select the text you want to transform and click the "rot13" button (or press ''alt-R'').
*
* Known bugs
* - Should encode/decode the entire page (or just the content section) if nothing is selected.
* - Does not work on textbox content.
* - Only works in Mozilla (and maybe Safari?); an IE port should be possible, but would take a lot of work.
*/
var rot13map;
function rot13(a)
{
if (!rot13map) {
rot13map = new Array();
var s = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < s.length; i++)
rot13map = s.charAt((i+13)%26);
s = s.toUpperCase();
for (var i = 0; i < s.length; i++)
rot13map = s.charAt((i+13)%26);
}
var s = "";
for (var i = 0; i < a.length; i++) {
var b = rot13map;
s += (b ? b : a.charAt(i));
}
//alert("rot13('"+a+"') = '"+s+"'");
return s;
}
function getTextNodesInRange (range) {
var retVal = new Array();
retVal.startOffset = retVal.endOffset = -1;
var nodes = retVal.nodes = new Array();
var currNode = range.startContainer;
var lastNode = range.endContainer;
if (currNode.nodeType == 3)
retVal.startOffset = range.startOffset;
else if (currNode.firstChild)
currNode = currNode.childNodes;
if (lastNode.nodeType == 3)
retVal.endOffset = range.endOffset;
else if (lastNode.firstChild)
lastNode = (range.endOffset > 0 ? lastNode.childNodes : lastNode.prevSibling);
search:
while (currNode) {
while (currNode.firstChild)
if ((currNode = currNode.firstChild) == lastNode) break;
if (currNode.nodeType == 3)
nodes.push(currNode);
if (currNode == lastNode)
break;
while (!currNode.nextSibling)
if ((currNode = currNode.parentNode) == lastNode) break search;
currNode = currNode.nextSibling;
}
if (retVal.startOffset < 0)
retVal.startOffset = 0;
if (retVal.endOffset < 0)
retVal.endOffset = (nodes.length ? nodes.length : 0);
return retVal;
}
function rot13Selection () {
if (!window.getSelection && !document.getSelection) {
alert("Browser does not support getSelection().");
return;
}
var selection = (window.getSelection ? window.getSelection() : document.getSelection());
if (!selection || selection.isCollapsed) return;
if (!selection.getRangeAt) {
alert("Browser does not support selection.getRangeAt().");
return;
}
var texts = new Array();
for (var i = 0; i < selection.rangeCount; i++) {
var textNodes = getTextNodesInRange(selection.getRangeAt(i));
//alert("processing "+textNodes.nodes.length+" nodes");
texts.push(textNodes);
var j = 0;
if (textNodes.nodes.length < 1)
continue;
else if (textNodes.nodes.length < 2)
textNodes.nodes.nodeValue = (textNodes.nodes.nodeValue.substring(0, textNodes.startOffset) +
rot13(textNodes.nodes.nodeValue.substring(textNodes.startOffset, textNodes.endOffset)) +
textNodes.nodes.nodeValue.substring(textNodes.endOffset));
else {
textNodes.nodes.nodeValue = (textNodes.nodes.nodeValue.substring(0, textNodes.startOffset) +
rot13(textNodes.nodes.nodeValue.substring(textNodes.startOffset)));
for (j = 1; j < textNodes.nodes.length-1; j++)
textNodes.nodes.nodeValue = rot13(textNodes.nodes.nodeValue);
textNodes.nodes.nodeValue = (rot13(textNodes.nodes.nodeValue.substring(0, textNodes.endOffset)) +
textNodes.nodes.nodeValue.substring(textNodes.endOffset));
}
}
selection = window.getSelection();
selection.removeAllRanges();
for (var i = 0; i < texts.length; i++) {
if (texts.nodes.length < 1) continue;
var range = document.createRange();
range.setStart(texts.nodes, texts.startOffset);
range.setEnd(texts.nodes.nodes.length-1], texts.endOffset);
selection.addRange(range);
}
}
addOnloadHook(function () {
mw.util.addPortletLink('p-cactions', 'javascript:rot13Selection()', 'rot13', 'ca-rot13', 'Encrypt/decrypt selection with ROT-13', 'R');
});