Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | |
3 * Copyright (C) 2006-2016 Eyeo GmbH | |
4 * | |
5 * Adblock Plus is free software: you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License version 3 as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * Adblock Plus is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
16 */ | |
17 | |
18 /** @module contentBlocking */ | |
19 | |
20 "use strict"; | |
21 | |
22 let {Prefs} = require("prefs"); | |
23 let {ContentBlockerList} = require("abp2blocklist"); | |
24 let {FilterStorage} = require("filterStorage"); | |
25 let {FilterNotifier} = require("filterNotifier"); | |
26 let {port} = require("messaging"); | |
27 | |
28 let contentBlockingSupported = "setContentBlocker" in safari.extension; | |
29 let legacyApiSupported = "onbeforeload" in Element.prototype; | |
kzar
2016/04/19 14:03:49
I remember you said we shouldn't assume both onbef
Sebastian Noack
2016/05/12 11:12:23
You could detect the legacy API in the content scr
kzar
2016/05/17 15:15:39
Done.
| |
30 let contentBlockingActive = contentBlockingSupported && !legacyApiSupported; | |
31 let afterContentBlockingFinished; | |
Sebastian Noack
2016/05/12 11:12:23
If I understand the logic correctly, this variable
kzar
2016/05/17 15:15:39
Done.
| |
32 let contentBlockListDirty = true; | |
33 let lastSetContentBlockerResult; | |
34 | |
35 function clearBlockCounters() | |
36 { | |
37 ext.pages.query({}, pages => | |
38 { | |
39 for (let page of pages) | |
40 page.browserAction.setBadge(); | |
41 }); | |
42 } | |
43 | |
44 function setContentBlocker(callback) | |
45 { | |
46 // setContentBlocker returns null if given the same blocklist as last time, | |
47 // even when there was an error. (It's also wasteful to re-generate the | |
48 // blocklist when nothing has changed!) | |
49 if (!contentBlockListDirty) | |
50 { | |
51 callback(lastSetContentBlockerResult); | |
52 return; | |
53 } | |
54 | |
55 let contentBlockerList = new ContentBlockerList(); | |
56 for (let subscription of FilterStorage.subscriptions) | |
57 if (!subscription.disabled) | |
58 for (let filter of subscription.filters) | |
59 contentBlockerList.addFilter(filter); | |
60 | |
61 safari.extension.setContentBlocker( | |
62 // setContentBlocker seems to work unreliably in Safari 9 unless the the | |
63 // given rules are converted to JSON first. (An error is sometimes thrown: | |
64 // "Extension compilation failed: Failed to parse the JSON String.") | |
65 JSON.stringify(contentBlockerList.generateRules()), | |
Sebastian Noack
2016/05/12 11:12:23
That needs to be tracked down properly. If there i
kzar
2016/05/17 15:15:39
OK, I'll try again to figure out what's going on.
| |
66 function (result) | |
67 { | |
68 contentBlockListDirty = false; | |
69 lastSetContentBlockerResult = result; | |
70 callback(result); | |
71 } | |
72 ); | |
73 } | |
74 | |
75 function updateContentBlocker(onStartup) | |
Sebastian Noack
2016/05/12 11:12:23
Nit: onStartup -> isStartup, since this value indi
kzar
2016/05/17 15:15:39
Done.
| |
76 { | |
77 afterContentBlockingFinished = new Promise(resolve => | |
78 { | |
79 setContentBlocker(result => | |
80 { | |
81 if (result instanceof Error) | |
82 { | |
83 let suppressErrorMessage = false; | |
84 | |
85 // If the content blocking API fails the first time it's used the | |
86 // legacy blocking API (if available) won't have been disabled. | |
87 if (!contentBlockingActive && legacyApiSupported) | |
88 { | |
89 Prefs["safariContentBlocker"] = false; | |
90 Prefs.on("safariContentBlocker", onSafariContentBlocker); | |
91 // If content blocking failed on startup and we're switching back to | |
92 // the legacy API anyway we don't need to show an error message. | |
93 if (onStartup) | |
94 suppressErrorMessage = true; | |
95 } | |
96 | |
97 if (!suppressErrorMessage) | |
98 alert(result.message); | |
99 } | |
100 else if (!contentBlockingActive) | |
101 { | |
102 contentBlockingActive = true; | |
103 clearBlockCounters(); | |
104 } | |
105 | |
106 resolve(contentBlockingActive); | |
107 afterContentBlockingFinished = undefined; | |
108 }); | |
109 }); | |
110 } | |
111 | |
112 function onSafariContentBlocker() | |
113 { | |
114 Prefs.off("safariContentBlocker", onSafariContentBlocker); | |
115 updateContentBlocker(); | |
116 } | |
117 | |
118 if (contentBlockingSupported) | |
119 { | |
120 Promise.all([Prefs.untilLoaded, FilterNotifier.once("load")]).then(() => | |
121 { | |
122 // If this version of Safari only supports the new API then let's make sure | |
123 // the safariContentBlocker preference is set to true for consistency. | |
124 if (contentBlockingActive) | |
125 Prefs["safariContentBlocker"] = true; | |
126 | |
127 if (Prefs["safariContentBlocker"]) | |
Sebastian Noack
2016/05/12 11:12:23
Nit: Prefs.safariContentBlocker
kzar
2016/05/17 15:15:38
Done.
| |
128 updateContentBlocker(true); | |
129 else | |
130 Prefs.on("safariContentBlocker", onSafariContentBlocker); | |
Sebastian Noack
2016/05/12 11:12:23
I wonder whether the logic wouldn't be simpler if
kzar
2016/05/17 15:15:40
Done.
| |
131 | |
132 for (let action of ["load", "subscription.added", "subscription.removed", | |
Sebastian Noack
2016/05/12 11:12:23
As usual, jsHydra will duplicate that array in the
kzar
2016/05/17 15:15:38
Done.
| |
133 "subscription.updated", "subscription.disabled", | |
134 "filter.added", "filter.removed", "filter.disabled"]) | |
135 FilterNotifier.on(action, () => | |
136 { | |
137 contentBlockListDirty = true; | |
138 if (contentBlockingActive) | |
139 updateContentBlocker(); | |
140 }); | |
141 }); | |
142 } | |
143 | |
144 port.on("safari.contentBlockingActive", function(msg, sender) | |
145 { | |
146 if (!contentBlockingActive && afterContentBlockingFinished) | |
147 return afterContentBlockingFinished; | |
148 return contentBlockingActive; | |
149 }); | |
150 | |
OLD | NEW |