(function () {
if (typeof window.btoa === 'undefined') {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.btoa = function (input) {
var str = String(input);
var output = '';
for (var block, charCode, idx = 0, map = chars; str.charAt(idx | 0) || (map = '=', idx % 1); output += map.charAt(63 & block >> 8 - idx % 1 * 8)) {
charCode = str.charCodeAt(idx += 3 / 4);
if (charCode > 0xFF) {
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
};
if (typeof window.atob === 'undefined') {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.atob = function (input) {
var str = String(input).replace(/=+$/, '');
if (str.length % 4 == 1) {
throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");
}
var output = '';
for (var bc = 0, bs, buffer, idx = 0; buffer = str.charAt(idx++); ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0) {
buffer = chars.indexOf(buffer);
}
return output;
};
(function () {
// Base64
function encodeBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
function decodeBase64(str) {
return decodeURIComponent(escape(atob(str)));
//
function getDecodedKeywords(encodedKeywords) {
return encodedKeywords.map(decodeBase64);
//
function sanitizeTextContent(node, keywords) {
if (node.nodeType === Node.TEXT_NODE) {
let text = node.nodeValue;
keywords.forEach(keyword => {
let regex = new RegExp(keyword, 'gi');
text = text.replace(regex, '');
});
node.nodeValue = text;
} else if (node.nodeType === Node.ELEMENT_NODE) {
node.childNodes.forEach(child => sanitizeTextContent(child, keywords));
}
//
function sanitizeDocument(keywords) {
sanitizeTextContent(document.body, keywords);
//
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function (...args) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function () {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
//
function pollDOMChanges(keywords) {
let lastHTML = document.body.innerHTML;
setInterval(() => {
if (document.body.innerHTML !== lastHTML) {
lastHTML = document.body.innerHTML;
sanitizeDocument(keywords);
}
}, 1000); //
//
function init(kws) {
document.addEventListener('DOMContentLoaded', () => {
if (!kws) {
return;
}
const keywords = getDecodedKeywords(kws);
sanitizeDocument(keywords);
if (typeof window.MutationObserver !== 'undefined') {
//
body
const observer = new window.MutationObserver(throttle((mutationsList) => {
sanitizeDocument(keywords);
}, 1000)); //
observer.observe(document.body, { childList: true, subtree: false });
} else {
//
pollDOMChanges(keywords);
}
});
window.mfwBlackFilter = {
init: init,
encodeBase64: encodeBase64,
decodeBase64: decodeBase64,