cloudfuck/content-script.js

129 lines
4.3 KiB
JavaScript

const resources = {
"cf_red": browser.runtime.getURL('images/pure-evil.png')
};
const gatekeepers = {
// "here-goes-hostname-of-your-local-searx-instance": "searx",
"html.duckduckgo.com": "duckduckgo"
};
const modules = {
"searx": {
"check": function() {
return document.body.classList.contains('results_endpoint');
},
"trigger": function(link, cloudfucked) {
if (!link.querySelector('.cloudfuck_market')) {
let market = document.createElement('img');
market.classList.add('cloudfuck_market');
market.setAttribute('data-test', cloudfucked);
if (cloudfucked) {
market.alt = 'cloudflare';
market.src = resources.cf_red;
market.style.height = '1em';
market.style.marginRight = '0.5em';
}
link.prepend(market);
}
},
"init": function(hosts, port) {
function getPages() {
return document.querySelectorAll('#main_results hr').length + 1;
}
let pages = getPages();
this.parse(hosts, port);
addEventListener('scroll', () => {
if (getPages() > pages) {
modules.searx.parse(hosts, port);
pages = getPages();
}
});
},
"parse": function(hosts, port) {
Array.from(document.querySelectorAll('.result-default'))
.forEach((el) => {
let link = el.querySelector('a');
let hostname = new URL(link.href).hostname;
if (!(hostname in hosts)) {
hosts[hostname] = {
"links": [link],
"cloudfucked": null
};
} else {
hosts[hostname].links.push(link);
}
});
makeTest(hosts, port);
}
},
"duckduckgo": {
"check": function() {
return document.body.classList.contains('body--html');
},
"trigger": function(link, cloudfucked) {
if (!link.querySelector('.cloudfuck_market')) {
let market = document.createElement('img');
market.classList.add('cloudfuck_market');
market.setAttribute('data-test', cloudfucked);
if (cloudfucked) {
market.alt = 'cloudflare';
market.src = resources.cf_red;
market.style.height = '1em';
market.style.marginRight = '0.5em';
}
link.prepend(market);
}
},
"init": function(hosts, port) {
this.parse(hosts, port);
},
"parse": function(hosts, port) {
Array.from(document.querySelectorAll('.result__a'))
.forEach((link) => {
let hostname = new URL(link.href).hostname;
if (!(hostname in hosts)) {
hosts[hostname] = {
"links": [link],
"cloudfucked": null
};
} else {
hosts[hostname].links.push(link);
}
});
makeTest(hosts, port);
}
}
};
function loadModule(name) {
if (!(name in modules)) {
throw new Error(`unknown module ${name}`);
}
const module = modules[name];
if (module.check()) {
const port = browser.runtime.connect();
let hosts = [];
port.onMessage.addListener((data) => {
hosts[data.hostname].cloudfucked = data.cloudfucked;
hosts[data.hostname].links.forEach((link) => {
module.trigger(link, data.cloudfucked);
});
});
// TODO: fix this crap
module.init(hosts, port);
}
}
function makeTest(hosts, port) {
for (hostname in hosts) {
let host = hosts[hostname];
if (host.cloudfucked === null) {
port.postMessage({
"action": "test",
hostname
});
}
}
}
let engine = gatekeepers[location.hostname];
if (typeof engine !== 'undefined') {
loadModule(engine);
}