OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 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/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 /** | 18 /** |
19 * @fileOverview Element hiding implementation. | 19 * @fileOverview Element hiding implementation. |
20 */ | 20 */ |
21 | 21 |
22 Cu.import("resource://gre/modules/Services.jsm"); | 22 Cu.import("resource://gre/modules/Services.jsm"); |
23 | 23 |
24 let {Utils} = require("utils"); | 24 let {Utils} = require("utils"); |
25 let {IO} = require("io"); | 25 let {IO} = require("io"); |
26 let {Prefs} = require("prefs"); | 26 let {Prefs} = require("prefs"); |
27 let {ElemHideException} = require("filterClasses"); | 27 let {ElemHideException} = require("filterClasses"); |
28 let {FilterNotifier} = require("filterNotifier"); | 28 let {FilterNotifier} = require("filterNotifier"); |
29 let {AboutHandler} = require("elemHideHitRegistration"); | |
30 | 29 |
31 /** | 30 /** |
32 * Lookup table, filters by their associated key | 31 * Lookup table, filters by their associated key |
33 * @type Object | 32 * @type Object |
34 */ | 33 */ |
35 let filterByKey = Object.create(null); | 34 let filterByKey = Object.create(null); |
36 | 35 |
37 /** | 36 /** |
38 * Lookup table, keys of the filters by filter text | 37 * Lookup table, keys of the filters by filter text |
39 * @type Object | 38 * @type Object |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 * Inidicates whether the element hiding stylesheet is currently applied. | 73 * Inidicates whether the element hiding stylesheet is currently applied. |
75 * @type Boolean | 74 * @type Boolean |
76 */ | 75 */ |
77 applied: false, | 76 applied: false, |
78 | 77 |
79 /** | 78 /** |
80 * Called on module startup. | 79 * Called on module startup. |
81 */ | 80 */ |
82 init: function() | 81 init: function() |
83 { | 82 { |
| 83 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] |
| 84 .getService(Ci.nsIMessageListenerManager); |
| 85 let hitHandler = (message => { |
| 86 let result = ElemHide.shouldHide(message.data); |
| 87 let target = message.target.QueryInterface(Ci.nsIMessageSender); |
| 88 target.sendAsyncMessage(message.data.responseMessage, result); |
| 89 }); |
| 90 messageManager.addMessageListener("AdblockPlus:ElemHideHit", hitHandler); |
| 91 onShutdown.add(() => messageManager.removeMessageListener("AdblockPlus:ElemH
ideHit", hitHandler)); |
| 92 |
84 Prefs.addListener(function(name) | 93 Prefs.addListener(function(name) |
85 { | 94 { |
86 if (name == "enabled") | 95 if (name == "enabled") |
87 ElemHide.apply(); | 96 ElemHide.apply(); |
88 }); | 97 }); |
89 onShutdown.add(function() | 98 onShutdown.add(() => ElemHide.unapply()); |
90 { | |
91 ElemHide.unapply(); | |
92 }); | |
93 | 99 |
94 let styleFile = IO.resolveFilePath(Prefs.data_directory); | 100 let styleFile = IO.resolveFilePath(Prefs.data_directory); |
95 styleFile.append("elemhide.css"); | 101 styleFile.append("elemhide.css"); |
96 styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); | 102 styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); |
97 }, | 103 }, |
98 | 104 |
99 /** | 105 /** |
100 * Removes all known filters | 106 * Removes all known filters |
101 */ | 107 */ |
102 clear: function() | 108 clear: function() |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 188 |
183 let list = exceptions[filter.selector]; | 189 let list = exceptions[filter.selector]; |
184 for (let i = list.length - 1; i >= 0; i--) | 190 for (let i = list.length - 1; i >= 0; i--) |
185 if (list[i].isActiveOnDomain(docDomain)) | 191 if (list[i].isActiveOnDomain(docDomain)) |
186 return list[i]; | 192 return list[i]; |
187 | 193 |
188 return null; | 194 return null; |
189 }, | 195 }, |
190 | 196 |
191 /** | 197 /** |
| 198 * Processes an element hiding hit |
| 199 * @param {String} message.key |
| 200 * key of the matching element hiding rule |
| 201 * @param {Object[]} message.frames |
| 202 * information required to reconstruct frame |
| 203 * data for the hit |
| 204 * @return {Boolean} |
| 205 */ |
| 206 shouldHide: function(message) |
| 207 { |
| 208 let filter = ElemHide.getFilterByKey(message.key); |
| 209 if (!filter || !message.frames.length) |
| 210 return false; |
| 211 |
| 212 let fakeFrame = null; |
| 213 for (let i = message.frames.length - 1; i >= 0; i--) |
| 214 { |
| 215 fakeFrame = { |
| 216 parent: fakeFrame, |
| 217 location: { |
| 218 href: message.frames[i].location |
| 219 }, |
| 220 document: { |
| 221 documentElement: {} |
| 222 }, |
| 223 QueryInterface: function() {return this;}, |
| 224 getInterface: function() {return this;}, |
| 225 usePrivateBrowsing: (fakeFrame ? fakeFrame.usePrivateBrowsing : message.
frames[i].privateBrowsing) |
| 226 }; |
| 227 fakeFrame.top = fakeFrame.parent || fakeFrame; |
| 228 if (!fakeFrame.parent) |
| 229 fakeFrame.parent = fakeFrame; |
| 230 |
| 231 let sitekey = message.frames[i].sitekey || null; |
| 232 fakeFrame.document.documentElement.getAttribute = function(attr) |
| 233 { |
| 234 if (attr == "data-adblockkey") |
| 235 return sitekey; |
| 236 else |
| 237 return null; |
| 238 }; |
| 239 } |
| 240 |
| 241 let {Policy} = require("contentPolicy"); |
| 242 return !Policy.processNode(fakeFrame, fakeFrame.document, Policy.type.ELEMHI
DE, filter); |
| 243 }, |
| 244 |
| 245 /** |
192 * Will be set to true if apply() is running (reentrance protection). | 246 * Will be set to true if apply() is running (reentrance protection). |
193 * @type Boolean | 247 * @type Boolean |
194 */ | 248 */ |
195 _applying: false, | 249 _applying: false, |
196 | 250 |
197 /** | 251 /** |
198 * Will be set to true if an apply() call arrives while apply() is already | 252 * Will be set to true if an apply() call arrives while apply() is already |
199 * running (delayed execution). | 253 * running (delayed execution). |
200 * @type Boolean | 254 * @type Boolean |
201 */ | 255 */ |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 | 360 |
307 if (!hasFilters) | 361 if (!hasFilters) |
308 throw Cr.NS_ERROR_NOT_AVAILABLE; | 362 throw Cr.NS_ERROR_NOT_AVAILABLE; |
309 | 363 |
310 function escapeChar(match) | 364 function escapeChar(match) |
311 { | 365 { |
312 return "\\" + match.charCodeAt(0).toString(16) + " "; | 366 return "\\" + match.charCodeAt(0).toString(16) + " "; |
313 } | 367 } |
314 | 368 |
315 // Return CSS data | 369 // Return CSS data |
316 let cssTemplate = "-moz-binding: url(about:" + AboutHandler.aboutPrefix + "?
%ID%#dummy) !important;"; | 370 let cssTemplate = "-moz-binding: url(about:abp-elemhidehit?%ID%#dummy) !impo
rtant;"; |
317 for (let domain in domains) | 371 for (let domain in domains) |
318 { | 372 { |
319 let rules = []; | 373 let rules = []; |
320 let list = domains[domain]; | 374 let list = domains[domain]; |
321 | 375 |
322 if (domain) | 376 if (domain) |
323 yield ('@-moz-document domain("' + domain.split(",").join('"),domain("')
+ '"){').replace(/[^\x01-\x7F]/g, escapeChar); | 377 yield ('@-moz-document domain("' + domain.split(",").join('"),domain("')
+ '"){').replace(/[^\x01-\x7F]/g, escapeChar); |
324 else | 378 else |
325 { | 379 { |
326 // Only allow unqualified rules on a few protocols to prevent them from
blocking chrome | 380 // Only allow unqualified rules on a few protocols to prevent them from
blocking chrome |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 let filter = filterByKey[key]; | 438 let filter = filterByKey[key]; |
385 if (specificOnly && (!filter.domains || filter.domains[""])) | 439 if (specificOnly && (!filter.domains || filter.domains[""])) |
386 continue; | 440 continue; |
387 | 441 |
388 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) | 442 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) |
389 result.push(filter.selector); | 443 result.push(filter.selector); |
390 } | 444 } |
391 return result; | 445 return result; |
392 } | 446 } |
393 }; | 447 }; |
OLD | NEW |