If you cannot read this, original source code wont change anything!
That's a wee bit unfair - Just because somebody doesn't know what to make of...
$(e).find("a").length && (r *= 2)
...doesn't mean they won't know what this does:
if ($(element).find("a").length > 0) { score = score * 2 }
And the minified code - though possibly even the input - makes use of quite a few such tricks and programmer shorthands.
refactored+annotated (making no claim that it still works, or even that I got it right - I certainly wouldn't use it): http://pastebin.com/CTXaCnkpBut for most people with concerns, this is the only bit of code that does anything they should care about:
$(i[a]).attr("style", "opacity: 0; pointer-events: none")
All it does is make the entire signature fully transparent and unresponsive to clicks/taps, and that bit of code is only called if the signature scores badly. There's certainly no communication with a mothership or secret background bitcoin mining on your CPU etc. going on. (as of this post)
Your annotated code is actually pretty close to the original source! The main reason I use mimify the script with uglifyjs is because it removes my debug statements, which there are a lot of. In the interest of openness, here is a version that has minimal uglification applied to it:
bct_adblock.no_debug.js. The creation and upload of the not-so-minified version is built into my upload scripts so it should be up to date with any future updates.
For reference, below is the original source, with debugging removed. If you want to understand how the script works, TheRealSteve is the way to go because it has annotations.
function isAnnoyingCharacter(char)
{
var code = char.charCodeAt();
var ranges = [[0x2500, 0x256F],
[0x2580, 0x259F],
[0x25A0, 0x25FF],
];
for(var i = 0; i < ranges.length; i++)
if(code > ranges[i][0] && code <= ranges[i][1])
return true;
return false;
}
function calculateAnnoyingCharacter(element)
{
var childNodes = Array.prototype.slice.call(element.childNodes);
var result = childNodes.reduce(
function(prev, current, index)
{
if(current.nodeType == 1)
return prev + calculateAnnoyingCharacter(current);
if(current.nodeType == 3)
{
var count = 0;
for (c of current.nodeValue)
if(isAnnoyingCharacter(c))
count++;
var size = Number(getComputedStyle(current.parentNode).fontSize.match(/(\d*(\.\d*)?)px/)[1]);
return prev + size*size*count;
}
return prev;
}, 0);
return result;
}
function getFormattingRate(context)
{
var result = 0;
if(context.backgroundColor)
return 1;
if(context.fontSize >= 14)
result += 0.05 + Math.max(0, (context.fontsize - 14)*0.03);
if(context.color)
result += 0.2;
if(context.font)
result += 0.03;
if(context.underline)
result += 0.02;
if(context.bold)
result += 0.04;
if(context.table)
result += 0.2;
return Math.min(result, 1);
}
function calculateFormattingScore(element, context)
{
var previousContext = context;
if(typeof(context) === 'undefined')
previousContext = context = {};
else
context = $.extend({}, context);
if(element.style.fontSize && element.style.fontSize != "inherit")
context.fontsize = Number(element.style.fontSize.match(/(\d+)pt/)[1]);
if(element.style.color && element.style.color != "inherit")
context.color = true;
if(element.style.backgroundColor && element.style.backgroundColor != "inherit")
context.backgroundColor = true;
if(element.style.fontFamily && element.style.fontFamily != "inherit")
context.font = true;
if(element.style.textDecoration.indexOf("underline") != -1)
context.underline = true;
if(element.tagName == "B")
context.bold = true;
if(element.tagName == "TABLE")
context.table = true;
var score = $(element).width() * $(element).height() * getFormattingRate(context)
- $(element).width() * $(element).height() * getFormattingRate(previousContext);
var childNodes = Array.prototype.slice.call(element.childNodes);
score += childNodes.reduce(
function(prev, current, index)
{
if(current.nodeType == 1)
return prev + calculateFormattingScore(current, context);
return prev;
}, 0);
return score;
}
function isAd(div)
{
var score = 0;
score += calculateAnnoyingCharacter(div);
score += calculateFormattingScore(div);
score = Math.sqrt(score);
if($(div).find("a").length)
score *= 2;
return score > 100;
};
try
{
var signatures = $("div .signature");
for(var i = 0; i < signatures.length; i++)
{
if(isAd(signatures[i]))
{
$(signatures[i]).attr("style", "opacity: 0; pointer-events: none");
}
}
}
catch(e)
{
console.log(e);
}