OSDN Git Service

v1.7.6
[serene/MyBrowser.git] / app / electron / AdBlocker.js
1 const { app } = require('electron');
2 const { FiltersEngine, makeRequest } = require('@cliqz/adblocker');
3 const Axios = require('axios');
4 const fs = require('fs');
5 const path = require('path');
6 const tldts = require('tldts');
7
8 const lists = require('./Lists.json');
9
10 const Config = require('electron-store');
11 const config = new Config();
12
13 let engine;
14
15 if (!fs.existsSync(path.join(app.getPath('userData'), 'Files'))) {
16         fs.mkdirSync(path.join(app.getPath('userData'), 'Files'));
17 }
18
19 const ops = [];
20
21 const updateFilters = () => {
22         if (!fs.existsSync(path.join(app.getPath('userData'), 'Files'))) {
23                 fs.mkdirSync(path.join(app.getPath('userData'), 'Files'));
24         }
25
26         console.log('Downloading filters...');
27
28         for (const key in lists) {
29                 ops.push(Axios.get(lists[key]));
30         }
31
32         Axios.all(ops).then(res => {
33                 let data = '';
34
35                 for (const res1 of res) {
36                         data += res1.data;
37                 }
38
39                 console.log('Parsing filters...');
40
41                 engine = FiltersEngine.parse(data);
42
43                 console.log('Saving output...');
44
45                 fs.writeFile(path.resolve(path.join(app.getPath('userData'), 'Files', 'Ads.dat')), engine.serialize(), err => {
46                         if (err) return console.error(err);
47                         console.log('Complete.');
48                 });
49         });
50 }
51
52 module.exports.updateFilters = updateFilters;
53
54 module.exports.loadFilters = async () => {
55         const filePath = path.resolve(path.join(app.getPath('userData'), 'Files', 'Ads.dat'));
56
57         if (fs.existsSync(filePath)) {
58                 fs.readFile(path.resolve(filePath), (err, buffer) => {
59                         if (err) return console.error(err);
60
61                         try {
62                                 engine = FiltersEngine.deserialize(buffer);
63                         } catch (e) {
64                                 updateFilters();
65                         }
66                 });
67         } else {
68                 updateFilters();
69         }
70 };
71
72 module.exports.hasFile = () => {
73         const filePath = path.resolve(path.join(app.getPath('userData'), 'Files', 'Ads.dat'));
74
75         return fs.existsSync(filePath);
76 }
77
78 module.exports.isEnabled = () => {
79         return engine != undefined;
80 }
81
82 module.exports.runAdblockService = (window, windowId, id, session) => {
83         session.webRequest.onBeforeRequest({ urls: ['<all_urls>'] }, async (details, callback) => {
84                 if (engine && config.get('adBlocker')) {
85                         const { match, redirect } = engine.match(makeRequest({ type: details.resourceType, url: details.url }, tldts.parse));
86
87                         if (match || redirect) {
88                                 window.webContents.send(`blocked-ad-${windowId}`, { id });
89
90                                 if (redirect) {
91                                         callback({ redirectURL: redirect });
92                                 } else {
93                                         callback({ cancel: true });
94                                 }
95
96                                 return;
97                         }
98                 }
99
100                 callback({ cancel: false });
101         });
102 }
103
104 module.exports.removeAds = (url, webContents) => {
105         if (engine == undefined) return;
106         const { styles, scripts } = engine.getCosmeticsFilters({
107                 url,
108                 ...tldts.parse(url),
109         });
110
111         webContents.insertCSS(styles);
112
113         for (const script of scripts) {
114                 console.log(script);
115                 webContents.executeJavaScript(script);
116         }
117 }