// ==UserScript==
// @name Primel Dozenator
// @namespace http://userscripts.org/users/322169
// @version 0.1.0
// @description Converts the site-generated numbers on Dozensonline into dozenal, as they should be.
// @include http://z13.invisionfree.com/DozensOnline/*
// @copyright 2015, John Volan
// ==/UserScript==
(function() {
var dChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
var zChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Ӿ', 'Ɛ'];
var intPrefix = '';
var fractPrefix = ''
var point = '.';
var annotation = '<sub>z</sub>'
var addAnnotation = true;
var primelTime = true;
var primelDatePrefix = '';
var primelDateSuffix = ' trices';
// 'd' for "decimal".
function convert(dText) {
dText += '';
var number = 0;
for (var i = 0; i < dText.length; i++) {
if (dText[i] == ',') continue;
number *= 10;
number += dChars.indexOf(dText[i]);
}
if (number === 0) return '0' + annotation;
var text = '';
var pow = Math.floor(Math.log(number) / (Math.log(12) || 1));
do {
var digit = Math.floor(number / Math.pow(12, pow));
text += zChars[digit];
number -= digit * Math.pow(12, pow--);
}
while (pow >= 0 || number > 0);
if (addAnnotation)
return intPrefix + text + annotation;
else
return intPrefix + text;
}
function convertFract(dText) {
if (!dText) return '';
dText += '';
var number = 0;
var inFract = false, fractLength = 0;
var isPerCent = false;
for (var i = 0; i < dText.length; i++) {
if (dText[i] == '.') {
inFract = true;
continue;
}
if (dText[i] == '%') {
isPerCent = true;
break;
}
if (inFract) fractLength++;
number *= 10;
number += dChars.indexOf(dText[i]);
}
number /= Math.pow(10, fractLength) * (isPerCent ? 100 : 1);
return createFract(number, fractLength, isPerCent);
}
function createFract(number, fractLength, makePerGross) {
if (makePerGross) number *= 144;
var text = '';
var pow = Math.floor(Math.log(number) / (Math.log(12) || 1));
pow = Math.max(pow, 0);
do {
var digit = Math.floor(number / Math.pow(12, pow));
text += zChars[digit];
number -= digit * Math.pow(12, pow--);
}
while (pow >= 0);
if (fractLength > 0) {
text += point;
}
// Calculate an extra place to use in rounding
for (pow = -1; pow >= -fractLength - 1; pow--) {
var digit = Math.floor(number / Math.pow(12, pow));
text += zChars[digit];
number -= digit * Math.pow(12, pow);
}
return fractPrefix + round(text) + (makePerGross ? '%' : '') + annotation;
}
// 'z' for "dozenal".
function round(zText) {
if (zText[zText.length - 1] == point)
return round(zText.substr(0, zText.length - 1) + zChars[11]) + point;
else if (zChars.indexOf(zText[zText.length - 1]) >= 6) {
if (zText[zText.length - 2] == zChars[11])
return round(zText.substr(0, zText.length - 1)) + zChars[0];
else {
if (zText[zText.length - 2] == point)
return zText.substr(0, zText.length - 3) + zChars[zChars.indexOf(zText[zText.length - 3]) + 1] + point;
else
return zText.substr(0, zText.length - 2) + zChars[zChars.indexOf(zText[zText.length - 2]) + 1];
}
}
else {
return zText.substr(0, zText.length - 1);
}
}
// 's' for "sexagesimal".
function convertTime(sText, am) {
var hour = sText.substr(0, 2) % 12 + (am ? 0 : 12);
var minute = sText.substr(3, 2) * 1;
var minutes = hour * 60 + minute;
var trices = Math.round(minutes * 60 / 50);
var breathers = Math.floor(trices / 12);
var dwells = Math.floor(breathers / 12);
var trice = trices % 12;
var breather = breathers % 12;
var dwell = dwells % 12;
return primelDatePrefix + zChars[dwell] + zChars[breather] + zChars[trice] + annotation + primelDateSuffix;
}
function elConvert(element, pattern) {
element.innerHTML = element.innerHTML.replace(pattern, convert(element.innerHTML.match(pattern)));
}
function elConvertFract(element, pattern) {
element.innerHTML = element.innerHTML.replace(pattern, convertFract(element.innerHTML.match(pattern)));
}
function elConvertGlobal(element, pattern) {
var matches = element.innerHTML.match(pattern);
var startPos = 0;
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
startPos += element.innerHTML.substring(startPos).search(pattern);
var split = [element.innerHTML.substr(0, startPos), element.innerHTML.substr(startPos, match.length), element.innerHTML.substr(startPos + match.length)];
var result = convert(match);
element.innerHTML = split[0] + result + split[2];
startPos += result.length;
}
}
// number = 17;84 would have fractLength = 2.
function elCreateFract(element, pattern, number, fractLength, makePerGross) {
element.innerHTML = element.innerHTML.replace(pattern, createFract(number, fractLength, makePerGross));
}
function elConvertTime(element, pattern) {
var match = element.innerHTML.match(pattern) + '';
element.innerHTML = element.innerHTML.replace(match, convertTime(match.substr(0, 5), match.substr(6) == 'AM'));
}
function txtConvert(textNode, pattern) {
textNode.textContent = textNode.textContent.replace(pattern, convert(textNode.textContent.match(pattern)));
}
// Note to self: by default, regexes only match the first occurance.
// Also, * = 0 or more, + = 1 or more
(function() {
var el, els, i;
// Common elements:
elConvert(document.querySelector('b+a'), /\d/);
el = document.querySelector('.row4[align=center]>b');
elCreateFract(el, /.+/, parseFloat(el.innerHTML) / 50 * 1728, 4);
el = document.querySelector('.row4[align=center][style]');
el.innerHTML = el.innerHTML.replace('seconds', 'jiffs');
elConvert(el, /\d{4}(?= )/);
el = document.querySelector('.row4[align=center]>a:nth-of-type(2)');
elConvertGlobal(el, /\d+\b/g);
if (document.location.search == '?act=idx' || (document.location.search == '' && document.title.indexOf(' ') == -1)) {
// Main page
el = document.querySelector('#navstrip+br+div');
elConvert(el, /\b\d\d?(?= \d{4})/);
elConvert(el, /\d{4}/);
els = document.querySelectorAll('.row2[align]');
for (i = 0; i < els.length; i++)
elConvert(els[i], /.+/);
els = document.querySelectorAll('.row2[nowrap]');
for (i = 0; i < els.length; i++) {
elConvert(els[i], /\b\d\d?\b/);
elConvert(els[i], /\d{4}/);
}
el = document.querySelector('div>a+a+a');
el.innerHTML = el.innerHTML.replace('10', zChars[10] + annotation);
el = document.querySelector('.pformstrip');
elConvert(el, /\d+/);
el.innerHTML = el.innerHTML.replace('15 minutes', zChars[1] + zChars[6] + annotation + ' trices');
els = document.querySelectorAll('.row4:last-child>b');
for (i = 0; i < els.length - 1; i++) {
el = els[i];
if (el.innerHTML.match(/[0-9,]+/) == el.innerHTML)
elConvert(el, /.+/);
}
el = els[i];
elConvert(el, /\b\d\d?\b/);
elConvert(el, /\d{4}/);
if (primelTime) {
elConvertTime(document.querySelector('#navstrip+br+div'), /\b\d\d:\d\d [AP]M/);
els = document.querySelectorAll('.row2[nowrap]');
for (i = 0; i < els.length; i++)
elConvertTime(els[i], /\b\d\d:\d\d [AP]M/);
}
}
else if (document.location.search.indexOf('showforum=') != -1 || document.location.search.indexOf('act=SF') != -1) {
// Topic list
els = document.querySelectorAll('.row4:nth-child(5)>a, .row4:nth-child(6), .row2:nth-child(6)');
for (i = 0; i < els.length; i++)
if (els[i].innerHTML.indexOf('-') == -1)
elConvert(els[i], /.+/);
els = document.querySelectorAll('.row4:nth-child(7), .row2:nth-child(7)');
for (i = 0; i < els.length; i++) {
el = els[i].childNodes[0];
elConvert(el, /^\d\d?/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
el.innerHTML = el.innerHTML.replace(/st|nd|rd|th/, '');
}
/* els = document.querySelectorAll('[width="20%"]');
for (i = 0; i < els.length; i++) {
el = els[i];
txtConvert(el.childNodes[1], /\d+/);
elConvert(el.childNodes[2], /\d+/);
elConvert(el.childNodes[4], /\d+/);
} */
els = document.querySelectorAll('.row2:nth-child(3)');
for (i = 0; i < els.length; i++)
elConvert(els[i], /.+/);
els = document.querySelectorAll('.row2:nth-child(4)');
for (i = 0; i < els.length; i++)
if (els[i].innerHTML != els[i].innerText)
break;
else
elConvert(els[i], /.+/);
els = document.querySelectorAll('.row2:nth-child(5)');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
els = document.querySelectorAll('.darkrow2');
elConvertGlobal(els[els.length - 1], /\d+(?= )/g);
}
else if (document.location.search.indexOf('showtopic=') != -1 || document.location.search.indexOf('act=ST') != -1) {
els = document.querySelectorAll('.postdetails');
for (i = 0; i < els.length; i += 2) {
el = els[i];
elConvert(el, /\d\d?(?= )/);
elConvert(el, /\d{4}(?=,)/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
for (i = 1; i < els.length; i += 2) {
el = els[i];
elConvertGlobal(el, /[\d,]+(?=<br>\n)|\d\d?(?=-)/g);
el.innerHTML = el.innerHTML.replace(/\d\d(?=<br><br>)/, convert('20' + el.innerHTML.match(/\d\d(?=<br><br>)/)));
}
els = document.querySelectorAll('td:only-child:not([id])');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?(?= )/);
elConvert(el, /\d{4}(?=,)/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
els = document.querySelectorAll('.tablepad');
if (els.length == 2) {
var votes, totalVotes;
els = document.querySelectorAll('.tablepad>*>*>*>.row1>b');
votes = new Array(els.length);
for (i = 0; i < els.length; i++) {
votes[i] = parseInt(els[i].innerHTML.match(/\d+/));
elConvert(els[i], /\d+/);
}
el = document.querySelector('.tablepad>*>*>*>.row1:only-child');
totalVotes = parseInt(el.innerHTML.match(/\d+/));
elConvert(el, /\d+/);
if (totalVotes == 0)
totalVotes = 1;
els = document.querySelectorAll('.tablepad>*>*>*>.row1:last-child:not(:first-child)');
for (i = 0; i < els.length; i++)
elCreateFract(els[i], /\d{1,3}\.\d\d%(?=])/, votes[i] / totalVotes, 2, true);
}
els = document.querySelectorAll('a[title="Jump to page..."]');
if (els.length == 2) {
el = els[0].parentNode;
txtConvert(el.childNodes[1], /\d+/);
for (i = 2; i < el.childNodes.length; i += 2)
if (el.childNodes[i].innerText == 'Go to first unread post')
break;
else
if (el.childNodes[i].nodeType == 3)
txtConvert(el.childNodes[i], /\d+/);
else
elConvert(el.childNodes[i], /\d+/);
el = els[1].parentNode;
txtConvert(el.childNodes[2], /\d+/);
for (i = 3; i < el.childNodes.length; i += 2)
if (el.childNodes[i].nodeType == 3)
txtConvert(el.childNodes[i], /\d+/);
else
elConvert(el.childNodes[i], /\d+/);
}
els = document.querySelectorAll('.edit');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?(?= \d)/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
}
else if (/*document.location.search.indexOf('act=Post') != -1 ||*/ document.title.substr(0, 28) == 'Dozensonline -> Replying in ') {
els = document.querySelectorAll('td.row4:last-child');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?(?= )/);
elConvert(el, /\d{4}(?=,)/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
els = document.querySelectorAll('div.pformstrip');
for (i = 0; i < els.length; i++)
if (els[i].innerHTML == 'Last 10 Posts [ In reverse order ]') {
els[i].innerHTML = 'Last ' + zChars[10] + (addAnnotation ? annotation : '') + ' Posts [ In reverse order ]';
break;
}
els = document.querySelectorAll('td:only-child:not([id])');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?(?= \d)/);
elConvert(el, /\d{4}(?=,)/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
}
else if (document.location.search.indexOf('showuser=') != -1) {
els = document.querySelectorAll('.row1>b');
elConvert(els[0], /.+/);
el = els[2];
elConvert(el, /\d\d?(?=-)/);
var match = el.innerHTML.match(/\d\d$/);
el.innerHTML = el.innerHTML.replace(/\d\d$/, '20' + match);
elConvert(el, /\d{4}/);
elConvertFract(els[1], /\d+\.\d+/);
el = document.querySelector('tr:nth-child(5)>.row1');
elConvert(el, /\d\d?/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
annotation
el = document.querySelectorAll('.row1')[4];
elConvert(el, /\d\d?/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
el = document.querySelectorAll('.row1')[12];
elConvert(el, /\d\d?/);
elConvert(el, /\d{4}/);
el = document.querySelector('tr>.row1');
elConvertFract(el, /\d\d?\.\d\d%/);
el.innerHTML = el.innerHTML.replace('( ', '( ' + zChars[0] + point + zChars[0] + zChars[0] + annotation + ' ');
}
else if (document.location.search.indexOf('act=Search') != -1) {
els = document.querySelectorAll('.row4:nth-child(6), .row2:nth-child(7)');
for (i = 0; i < els.length; i++)
elConvert(els[i], /.+/);
els = document.querySelectorAll('.row2:nth-child(8)');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?(?= )/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
}
else if (document.location.search.indexOf('act=Msg') != -1) {
els = document.querySelectorAll('.row1');
for (i = 0; i < els.length; i++)
elConvertFract(els[i], /\d{1,3}%/);
els = document.querySelectorAll('.dlight>td:nth-child(4)');
for (i = 0; i < els.length; i++) {
el = els[i];
elConvert(el, /\d\d?/);
elConvert(el, /\d{4}/);
if (primelTime)
elConvertTime(el, /\d\d:\d\d [AP]M/);
}
elConvertGlobal(document.querySelector('i'), /\d+/g)
}
})();
})();