-
Notifications
You must be signed in to change notification settings - Fork 0
/
background.js
100 lines (85 loc) · 3.25 KB
/
background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const parseHostsFile = content => {
const fileLines = content.split('\n');
const adblockRules = fileLines.filter(line => {
const trimmedLine = line.trim();
return /^(#|!)/.test(trimmedLine) === false && trimmedLine !== '';
}).map(line => {
if (line.startsWith('||') && line.endsWith('^')) {
return line;
} else {
const lineParts = line.split(/\s+/);
const domain = lineParts[lineParts.length - 1];
return `||${domain}^`;
}
});
return adblockRules;
};
const removeRedundantRules = rules => {
const filteredRules = [];
const domainSet = new Set();
rules.forEach(rule => {
const domain = rule.slice(2, -1);
const baseDomain = domain.split('.').slice(-2).join('.');
if (!domainSet.has(baseDomain)) {
filteredRules.push(rule);
domainSet.add(baseDomain);
}
});
return filteredRules;
};
const generateFilter = (fileContents, fileName = 'blocklist.txt') => {
let duplicatesRemoved = 0;
const uniqueRules = new Set();
fileContents.forEach(content => {
const adblockRules = parseHostsFile(content);
adblockRules.forEach(rule => {
if (!uniqueRules.has(rule)) {
uniqueRules.add(rule);
} else {
duplicatesRemoved++;
}
});
});
const compressedRules = removeRedundantRules(uniqueRules);
const domainsCompressed = uniqueRules.size - compressedRules.length;
duplicatesRemoved += domainsCompressed;
const sortedRules = compressedRules.sort();
const header = generateHeader(sortedRules.length, duplicatesRemoved, domainsCompressed);
const filterContent = [header, ...sortedRules].join('\n');
const blob = new Blob([filterContent], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
return { filterContent, duplicatesRemoved, domainsCompressed };
};
const generateHeader = (domainCount, duplicatesRemoved, domainsCompressed) => {
const date = new Date().toISOString().slice(0, 10);
return `# Title: AdBlock Filter Generator
# Description: Chrome Extension to generate adblock syntax filter from multiple host files and blocklists
# Created: ${date}
# Domain Count: ${domainCount}
# Duplicates Removed: ${duplicatesRemoved}
# Domains Compressed: ${domainsCompressed}
#===============================================================`;
};
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
if (request.action === 'generateFilter') {
try {
console.log('Received file contents:', request.fileContents);
const { filterContent, duplicatesRemoved, domainsCompressed } = generateFilter(request.fileContents, request.fileName);
console.log('Generated filter content:', filterContent);
sendResponse({ success: true, duplicatesRemoved, domainsCompressed });
} catch (err) {
console.error('Error generating filter:', err);
sendResponse({ error: 'Error generating filter. Check the files and try again.' });
}
}
// Required for async response handling.
return true;
});