LEFT | RIGHT |
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 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 * Set of content types that aren't associated with a visual document area | 64 * Set of content types that aren't associated with a visual document area |
65 * @type Set | 65 * @type Set |
66 */ | 66 */ |
67 nonVisualTypes: new Set([ | 67 nonVisualTypes: new Set([ |
68 "SCRIPT", "STYLESHEET", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", | 68 "SCRIPT", "STYLESHEET", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", |
69 "ELEMHIDE", "POPUP", "GENERICHIDE", "GENERICBLOCK" | 69 "ELEMHIDE", "POPUP", "GENERICHIDE", "GENERICBLOCK" |
70 ]), | 70 ]), |
71 | 71 |
72 /** | 72 /** |
73 * Map containing all schemes that should be ignored by content policy. | 73 * Map containing all schemes that should be ignored by content policy. |
74 * @type Object | 74 * @type Set |
75 */ | 75 */ |
76 whitelistSchemes: new Set(), | 76 whitelistSchemes: new Set(), |
77 | 77 |
78 /** | 78 /** |
79 * Called on module startup, initializes various exported properties. | 79 * Called on module startup, initializes various exported properties. |
80 */ | 80 */ |
81 init: function() | 81 init: function() |
82 { | 82 { |
83 // Populate types map | 83 // Populate types map |
84 let iface = Ci.nsIContentPolicy; | 84 let iface = Ci.nsIContentPolicy; |
85 for (let name in iface) | 85 for (let name in iface) |
86 if (name.indexOf("TYPE_") == 0 && name != "TYPE_DATAREQUEST") | 86 if (name.indexOf("TYPE_") == 0 && name != "TYPE_DATAREQUEST") |
87 types.set(iface[name], name.substr(5)); | 87 types.set(iface[name], name.substr(5)); |
88 | 88 |
89 // whitelisted URL schemes | 89 // whitelisted URL schemes |
90 for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) | 90 for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) |
91 this.whitelistSchemes.add(scheme); | 91 this.whitelistSchemes.add(scheme); |
92 | 92 |
93 // Generate class identifier used to collapse node and register correspondin
g | 93 // Generate class identifier used to collapse node and register correspondin
g |
94 // stylesheet. | 94 // stylesheet. |
95 let offset = "a".charCodeAt(0); | 95 let offset = "a".charCodeAt(0); |
96 for (let i = 0; i < 20; i++) | 96 for (let i = 0; i < 20; i++) |
97 collapsedClass += String.fromCharCode(offset + Math.random() * 26); | 97 collapsedClass += String.fromCharCode(offset + Math.random() * 26); |
98 | 98 |
99 let collapseStyle = Services.io.newURI("data:text/css," + | 99 let collapseStyle = Services.io.newURI("data:text/css," + |
100 encodeURIComponent("." + collapsedClass + | 100 encodeURIComponent("." + collapsedClass + |
101 "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarb
azdummy) !important;}"), null, null); | 101 "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarb
azdummy) !important;}"), null, null); |
102 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi
ce.USER_SHEET); | 102 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi
ce.USER_SHEET); |
103 onShutdown.add(function() | 103 onShutdown.add(() => |
104 { | 104 { |
105 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.
USER_SHEET); | 105 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.
USER_SHEET); |
106 }); | 106 }); |
107 }, | 107 }, |
108 | 108 |
109 /** | 109 /** |
110 * Checks whether a node should be blocked, hides it if necessary | 110 * Checks whether a node should be blocked, hides it if necessary |
111 * @param wnd {nsIDOMWindow} | 111 * @param wnd {nsIDOMWindow} |
112 * @param node {nsIDOMElement} | 112 * @param node {nsIDOMElement} |
113 * @param contentType {String} | 113 * @param contentType {String} |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 return !match || match instanceof WhitelistFilter; | 246 return !match || match instanceof WhitelistFilter; |
247 }, | 247 }, |
248 | 248 |
249 /** | 249 /** |
250 * Checks whether the location's scheme is blockable. | 250 * Checks whether the location's scheme is blockable. |
251 * @param location {nsIURI} | 251 * @param location {nsIURI} |
252 * @return {Boolean} | 252 * @return {Boolean} |
253 */ | 253 */ |
254 isBlockableScheme: function(location) | 254 isBlockableScheme: function(location) |
255 { | 255 { |
256 return !Policy.whitelistSchemes.has(location.scheme); | 256 return !this.whitelistSchemes.has(location.scheme); |
257 }, | 257 }, |
258 | 258 |
259 /** | 259 /** |
260 * Checks whether a page is whitelisted. | 260 * Checks whether a page is whitelisted. |
261 * @param {String} url | 261 * @param {String} url |
262 * @param {String} [parentUrl] location of the parent page | 262 * @param {String} [parentUrl] location of the parent page |
263 * @param {String} [sitekey] public key provided on the page | 263 * @param {String} [sitekey] public key provided on the page |
264 * @return {Filter} filter that matched the URL or null if not whitelisted | 264 * @return {Filter} filter that matched the URL or null if not whitelisted |
265 */ | 265 */ |
266 isWhitelisted: function(url, parentUrl, sitekey) | 266 isWhitelisted: function(url, parentUrl, sitekey) |
267 { | 267 { |
268 if (!url) | 268 if (!url) |
269 return null; | 269 return null; |
270 | 270 |
271 // Do not apply exception rules to schemes on our whitelistschemes list. | 271 // Do not apply exception rules to schemes on our whitelistschemes list. |
272 let match = /^([\w\-]+):/.exec(url); | 272 let match = /^([\w\-]+):/.exec(url); |
273 if (match && Policy.whitelistSchemes.has(match[1])) | 273 if (match && this.whitelistSchemes.has(match[1])) |
274 return null; | 274 return null; |
275 | 275 |
276 if (!parentUrl) | 276 if (!parentUrl) |
277 parentUrl = url; | 277 parentUrl = url; |
278 | 278 |
279 // Ignore fragment identifier | 279 // Ignore fragment identifier |
280 let index = url.indexOf("#"); | 280 let index = url.indexOf("#"); |
281 if (index >= 0) | 281 if (index >= 0) |
282 url = url.substring(0, index); | 282 url = url.substring(0, index); |
283 | 283 |
284 let result = defaultMatcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT, g
etHostname(parentUrl), false, sitekey); | 284 let result = defaultMatcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT, g
etHostname(parentUrl), false, sitekey); |
285 return (result instanceof WhitelistFilter ? result : null); | 285 return (result instanceof WhitelistFilter ? result : null); |
286 }, | 286 }, |
287 | 287 |
288 /** | 288 /** |
289 * Checks whether the page loaded in a window is whitelisted for indication in
the UI. | 289 * Checks whether the page loaded in a window is whitelisted for indication in
the UI. |
290 * @param wnd {nsIDOMWindow} | 290 * @param wnd {nsIDOMWindow} |
291 * @return {Filter} matching exception rule or null if not whitelisted | 291 * @return {Filter} matching exception rule or null if not whitelisted |
292 */ | 292 */ |
293 isWindowWhitelisted: function(wnd) | 293 isWindowWhitelisted: function(wnd) |
294 { | 294 { |
295 return Policy.isWhitelisted(getWindowLocation(wnd)); | 295 return this.isWhitelisted(getWindowLocation(wnd)); |
296 }, | 296 }, |
297 | 297 |
298 /** | 298 /** |
299 * Asynchronously re-checks filters for given nodes. | 299 * Asynchronously re-checks filters for given nodes. |
300 * @param {Node[]} nodes | 300 * @param {Node[]} nodes |
301 * @param {RequestEntry} entry | 301 * @param {RequestEntry} entry |
302 */ | 302 */ |
303 refilterNodes: function(nodes, entry) | 303 refilterNodes: function(nodes, entry) |
304 { | 304 { |
305 // Ignore nodes that have been blocked already | 305 // Ignore nodes that have been blocked already |
(...skipping 24 matching lines...) Expand all Loading... |
330 { | 330 { |
331 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); | 331 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); |
332 registrar.registerFactory(this.classID, this.classDescription, this.contract
ID, this); | 332 registrar.registerFactory(this.classID, this.classDescription, this.contract
ID, this); |
333 | 333 |
334 let catMan = Utils.categoryManager; | 334 let catMan = Utils.categoryManager; |
335 for (let category of this.xpcom_categories) | 335 for (let category of this.xpcom_categories) |
336 catMan.addCategoryEntry(category, this.contractID, this.contractID, false,
true); | 336 catMan.addCategoryEntry(category, this.contractID, this.contractID, false,
true); |
337 | 337 |
338 Services.obs.addObserver(this, "content-document-global-created", true); | 338 Services.obs.addObserver(this, "content-document-global-created", true); |
339 | 339 |
340 onShutdown.add(function() | 340 onShutdown.add(() => |
341 { | 341 { |
342 Services.obs.removeObserver(this, "content-document-global-created"); | 342 Services.obs.removeObserver(this, "content-document-global-created"); |
343 | 343 |
344 for (let category of this.xpcom_categories) | 344 for (let category of this.xpcom_categories) |
345 catMan.deleteCategoryEntry(category, this.contractID, false); | 345 catMan.deleteCategoryEntry(category, this.contractID, false); |
346 | 346 |
347 registrar.unregisterFactory(this.classID, this); | 347 registrar.unregisterFactory(this.classID, this); |
348 }.bind(this)); | 348 }); |
349 }, | 349 }, |
350 | 350 |
351 // | 351 // |
352 // nsISupports interface implementation | 352 // nsISupports interface implementation |
353 // | 353 // |
354 | 354 |
355 QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver, | 355 QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver, |
356 Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]), | 356 Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]), |
357 | 357 |
358 // | 358 // |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 let uri = additional || subject.location.href; | 402 let uri = additional || subject.location.href; |
403 if (!Policy.processNode(subject.opener, subject.opener.document, "POPUP"
, uri, false)) | 403 if (!Policy.processNode(subject.opener, subject.opener.document, "POPUP"
, uri, false)) |
404 { | 404 { |
405 subject.stop(); | 405 subject.stop(); |
406 Utils.runAsync(() => subject.close()); | 406 Utils.runAsync(() => subject.close()); |
407 } | 407 } |
408 else if (uri == "about:blank") | 408 else if (uri == "about:blank") |
409 { | 409 { |
410 // An about:blank pop-up most likely means that a load will be | 410 // An about:blank pop-up most likely means that a load will be |
411 // initiated asynchronously. Wait for that. | 411 // initiated asynchronously. Wait for that. |
412 Utils.runAsync(function() | 412 Utils.runAsync(() => |
413 { | 413 { |
414 let channel = subject.QueryInterface(Ci.nsIInterfaceRequestor) | 414 let channel = subject.QueryInterface(Ci.nsIInterfaceRequestor) |
415 .getInterface(Ci.nsIDocShell) | 415 .getInterface(Ci.nsIDocShell) |
416 .QueryInterface(Ci.nsIDocumentLoader) | 416 .QueryInterface(Ci.nsIDocumentLoader) |
417 .documentChannel; | 417 .documentChannel; |
418 if (channel) | 418 if (channel) |
419 this.observe(subject, topic, data, channel.URI.spec); | 419 this.observe(subject, topic, data, channel.URI.spec); |
420 }); | 420 }); |
421 } | 421 } |
422 break; | 422 break; |
423 } | 423 } |
424 } | 424 } |
425 }, | 425 }, |
426 | 426 |
427 // | 427 // |
428 // nsIChannelEventSink interface implementation | 428 // nsIChannelEventSink interface implementation |
429 // | 429 // |
430 | 430 |
431 asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) | 431 asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) |
432 { | 432 { |
433 let result = Cr.NS_OK; | 433 let result = Cr.NS_OK; |
434 try | 434 try |
435 { | 435 { |
436 // nsILoadInfo.contentPolicyType was introduced in Gecko 35, then | 436 // nsILoadInfo.contentPolicyType was introduced in Gecko 35, then |
437 // renamed to nsILoadInfo.externalContentPolicyType in Gecko 44. | 437 // renamed to nsILoadInfo.externalContentPolicyType in Gecko 44. |
438 let loadInfo = oldChannel.loadInfo; | 438 let loadInfo = oldChannel.loadInfo; |
439 let contentType = loadInfo.externalContentPolicyType || loadInfo.contentPo
licyType; | 439 let contentType = ("externalContentPolicyType" in loadInfo ? |
| 440 loadInfo.externalContentPolicyType : loadInfo.contentPolicyType); |
440 if (!contentType) | 441 if (!contentType) |
441 return; | 442 return; |
442 | 443 |
443 let wnd = Utils.getRequestWindow(newChannel); | 444 let wnd = Utils.getRequestWindow(newChannel); |
444 if (!wnd) | 445 if (!wnd) |
445 return; | 446 return; |
446 | 447 |
447 if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT) | 448 if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT) |
448 { | 449 { |
449 if (wnd.history.length <= 1 && wnd.opener) | 450 if (wnd.history.length <= 1 && wnd.opener) |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 if (!wnd || wnd.closed) | 671 if (!wnd || wnd.closed) |
671 return; | 672 return; |
672 | 673 |
673 if (entry.type == "OBJECT") | 674 if (entry.type == "OBJECT") |
674 { | 675 { |
675 node.removeEventListener("mouseover", objectMouseEventHander, true); | 676 node.removeEventListener("mouseover", objectMouseEventHander, true); |
676 node.removeEventListener("mouseout", objectMouseEventHander, true); | 677 node.removeEventListener("mouseout", objectMouseEventHander, true); |
677 } | 678 } |
678 Policy.processNode(wnd, node, entry.type, entry.location, true); | 679 Policy.processNode(wnd, node, entry.type, entry.location, true); |
679 } | 680 } |
LEFT | RIGHT |