Index: lib/filterComposer.js |
=================================================================== |
--- a/lib/filterComposer.js |
+++ b/lib/filterComposer.js |
@@ -15,7 +15,10 @@ |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
-let {getDecodedHostname, stringifyURL} = require("url"); |
+let {extractHostFromFrame, stringifyURL, isThirdParty} = require("url"); |
+let {getKey, isFrameWhitelisted} = require("whitelisting"); |
+let {defaultMatcher} = require("matcher"); |
+let {WhitelistFilter} = require("filterClasses"); |
function escapeChar(chr) |
{ |
@@ -58,61 +61,76 @@ |
/** |
* Generates filters to block an element. |
* |
- * @param {string} tagName The element's tag name |
- * @param {string} [src] The element's "src" attribute |
- * @param {string} [id] The element's "id" attribute |
- * @param {string} [style] The element's "style" attribute |
- * @param {string[]} classes The classes given by the element's "class" attribute |
- * @param {string[]} urls The URLs considered when loading the element |
- * @param {URL} baseURL The URL of the document containing the element |
+ * @param {string} tagName The element's tag name |
+ * @param {Object} attributes The element's "id", "src" and "style attreibute |
+ * @param {string[]} classes The classes given by the element's "class" attribute |
+ * @param {string[]} urls The URLs considered when loading the element |
+ * @param {string} [type] The request type (will be ignored if there are no URLs) |
+ * @param {string} baseURL The URL of the document containing the element |
+ * @param {Page} page The page containing the element |
+ * @param {Frame} frame The frame containing the element |
* |
* @return {object} An object holding the list of generated filters and |
* the list of CSS selectors for the included element |
* hiding filters: {filters: [...], selectors: [...]} |
*/ |
-function composeFilters(tagName, id, src, style, classes, urls, baseURL) |
+function composeFilters(tagName, attributes, classes, urls, type, baseURL, page, frame) |
{ |
- // Add a blocking filter for each HTTP(S) URL associated with the element |
let filters = []; |
- for (let url of urls) |
+ let selectors = []; |
+ |
+ if (!isFrameWhitelisted(page, frame, "DOCUMENT")) |
{ |
- let urlObj = new URL(url, baseURL); |
- if (urlObj.protocol == "http:" || urlObj.protocol == "https:") |
+ let docDomain = extractHostFromFrame(frame); |
+ |
+ // Add a blocking filter for each URL of the element that can be blocked |
+ for (let url of urls) |
{ |
- let filter = stringifyURL(urlObj).replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); |
+ let urlObj = new URL(url, baseURL); |
- if (filters.indexOf(filter) == -1) |
- filters.push(filter); |
+ if (url.protocol == "http:" || url.protocol == "https:") |
+ { |
+ url = stringifyURL(urlObj); |
+ |
+ let filter = defaultMatcher.matchesAny( |
+ url, type, docDomain, |
+ isThirdParty(urlObj, docDomain), |
+ getKey(page, frame) |
+ ); |
+ |
+ if (!(filter instanceof WhitelistFilter)) |
+ { |
+ let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); |
+ |
+ if (filters.indexOf(filterText) == -1) |
+ filters.push(filterText); |
+ } |
+ } |
} |
- } |
- // If we couldn't generate any blocking filters, fallback to element hiding |
- let selectors = []; |
- if (filters.length == 0) |
- { |
- // Generate CSS selectors based on the element's "id" and "class" attribute |
- if (id) |
- selectors.push("#" + escapeCSS(id)); |
- if (classes.length > 0) |
- selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); |
+ // If we couldn't generate any blocking filters, fallback to element hiding |
+ let selectors = []; |
+ if (filters.length == 0 && !isFrameWhitelisted(page, frame, "ELEMHIDE")) |
+ { |
+ // Generate CSS selectors based on the element's "id" and "class" attribute |
+ if (attributes.id) |
+ selectors.push("#" + escapeCSS(attributes.id)); |
+ if (classes.length > 0) |
+ selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); |
- // If there is a "src" attribute, specifiying a URL that we can't block, |
- // generate a CSS selector matching the "src" attribute |
- if (src) |
- selectors.push(escapeCSS(tagName) + "[src=" + quoteCSS(src) + "]"); |
+ // If there is a "src" attribute, specifiying a URL that we can't block, |
+ // generate a CSS selector matching the "src" attribute |
+ if (attributes.src) |
+ selectors.push(escapeCSS(tagName) + "[src=" + quoteCSS(attributes.src) + "]"); |
- // As last resort, if there is a "style" attribute, and we couldn't generate |
- // any filters so far, generate a CSS selector matching the "style" attribute |
- if (style && selectors.length == 0 && filters.length == 0) |
- selectors.push(escapeCSS(tagName) + "[style=" + quoteCSS(style) + "]"); |
+ // As last resort, if there is a "style" attribute, and we couldn't generate |
+ // any filters so far, generate a CSS selector matching the "style" attribute |
+ if (attributes.style && selectors.length == 0 && filters.length == 0) |
+ selectors.push(escapeCSS(tagName) + "[style=" + quoteCSS(attributes.style) + "]"); |
- // Add an element hiding filter for each generated CSS selector |
- if (selectors.length > 0) |
- { |
- let domain = getDecodedHostname(baseURL).replace(/^www\./, ""); |
- |
+ // Add an element hiding filter for each generated CSS selector |
for (let selector of selectors) |
- filters.push(domain + "##" + selector); |
+ filters.push(docDomain.replace(/^www\./, "") + "##" + selector); |
} |
} |