Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/filterComposer.js

Issue 5693109165883392: Issue 2040 - Replaced localStorage with chrome.storage.local (Closed)
Patch Set: Rebased Created March 3, 2015, 3:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 let {extractHostFromFrame, stringifyURL, isThirdParty} = require("url"); 18 let {getDecodedHostname, stringifyURL} = require("url");
19 let {getKey, isFrameWhitelisted} = require("whitelisting");
20 let {defaultMatcher} = require("matcher");
21 let {WhitelistFilter} = require("filterClasses");
22 19
23 function escapeChar(chr) 20 function escapeChar(chr)
24 { 21 {
25 let code = chr.charCodeAt(0); 22 let code = chr.charCodeAt(0);
26 23
27 // Control characters and leading digits must be escaped based on 24 // Control characters and leading digits must be escaped based on
28 // their char code in CSS. Moreover, curly brackets aren't allowed 25 // their char code in CSS. Moreover, curly brackets aren't allowed
29 // in elemhide filters, and therefore must be escaped based on their 26 // in elemhide filters, and therefore must be escaped based on their
30 // char code as well. 27 // char code as well.
31 if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr)) 28 if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr))
(...skipping 21 matching lines...) Expand all
53 * @return {string} 50 * @return {string}
54 */ 51 */
55 function quoteCSS(value) 52 function quoteCSS(value)
56 { 53 {
57 return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"'; 54 return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"';
58 } 55 }
59 exports.quoteCSS = quoteCSS; 56 exports.quoteCSS = quoteCSS;
60 57
61 /** 58 /**
62 * Generates filters to block an element. 59 * Generates filters to block an element.
63 * @param {Object} details 60 *
64 * @param {string} details.tagName The element's tag name 61 * @param {string} tagName The element's tag name
65 * @param {string} detials.id The element's "id" attribute 62 * @param {string} [src] The element's "src" attribute
66 * @param {string} details.src The element's "src" attribute 63 * @param {string} [id] The element's "id" attribute
67 * @param {string} details.style The element's "style" attribute 64 * @param {string} [style] The element's "style" attribute
68 * @param {string[]} details.classes The classes given by the element's "class" attribute 65 * @param {string[]} classes The classes given by the element's "class" attribu te
69 * @param {string[]} details.urls The URLs considered when loading the eleme nt 66 * @param {string[]} urls The URLs considered when loading the element
70 * @param {string} details.type The request type (will be ignored if there are no URLs) 67 * @param {URL} baseURL The URL of the document containing the element
71 * @param {string} details.baseURL The URL of the document containing the ele ment
72 * @param {Page} details.page The page containing the element
73 * @param {Frame} details.frame The frame containing the element
74 * 68 *
75 * @return {object} An object holding the list of generated filters and 69 * @return {object} An object holding the list of generated filters and
76 * the list of CSS selectors for the included element 70 * the list of CSS selectors for the included element
77 * hiding filters: {filters: [...], selectors: [...]} 71 * hiding filters: {filters: [...], selectors: [...]}
78 */ 72 */
79 function composeFilters(details) 73 function composeFilters(tagName, id, src, style, classes, urls, baseURL)
80 { 74 {
75 // Add a blocking filter for each HTTP(S) URL associated with the element
81 let filters = []; 76 let filters = [];
82 let selectors = []; 77 for (let url of urls)
78 {
79 let urlObj = new URL(url, baseURL);
80 if (urlObj.protocol == "http:" || urlObj.protocol == "https:")
81 {
82 let filter = stringifyURL(urlObj).replace(/^[\w\-]+:\/+(?:www\.)?/, "||");
83 83
84 let page = details.page; 84 if (filters.indexOf(filter) == -1)
85 let frame = details.frame; 85 filters.push(filter);
86
87 if (!isFrameWhitelisted(page, frame, "DOCUMENT"))
88 {
89 let docDomain = extractHostFromFrame(frame);
90
91 // Add a blocking filter for each URL of the element that can be blocked
92 for (let url of details.urls)
93 {
94 let urlObj = new URL(url, details.baseURL);
95
96 if (urlObj.protocol == "http:" || urlObj.protocol == "https:")
97 {
98 url = stringifyURL(urlObj);
99
100 let filter = defaultMatcher.matchesAny(
101 url, details.type, docDomain,
102 isThirdParty(urlObj, docDomain),
103 getKey(page, frame)
104 );
105
106 if (!(filter instanceof WhitelistFilter))
107 {
108 let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||");
109
110 if (filters.indexOf(filterText) == -1)
111 filters.push(filterText);
112 }
113 }
114 }
115
116 // If we couldn't generate any blocking filters, fallback to element hiding
117 let selectors = [];
118 if (filters.length == 0 && !isFrameWhitelisted(page, frame, "ELEMHIDE"))
119 {
120 // Generate CSS selectors based on the element's "id" and "class" attribut e
121 if (details.id)
122 selectors.push("#" + escapeCSS(details.id));
123 if (details.classes.length > 0)
124 selectors.push(details.classes.map(c => "." + escapeCSS(c)).join(""));
125
126 // If there is a "src" attribute, specifiying a URL that we can't block,
127 // generate a CSS selector matching the "src" attribute
128 if (details.src)
129 selectors.push(escapeCSS(details.tagName) + "[src=" + quoteCSS(details.s rc) + "]");
130
131 // As last resort, if there is a "style" attribute, and we couldn't genera te
132 // any filters so far, generate a CSS selector matching the "style" attrib ute
133 if (details.style && selectors.length == 0 && filters.length == 0)
134 selectors.push(escapeCSS(details.tagName) + "[style=" + quoteCSS(details .style) + "]");
135
136 // Add an element hiding filter for each generated CSS selector
137 for (let selector of selectors)
138 filters.push(docDomain.replace(/^www\./, "") + "##" + selector);
139 } 86 }
140 } 87 }
141 88
89 // If we couldn't generate any blocking filters, fallback to element hiding
90 let selectors = [];
91 if (filters.length == 0)
92 {
93 // Generate CSS selectors based on the element's "id" and "class" attribute
94 if (id)
95 selectors.push("#" + escapeCSS(id));
96 if (classes.length > 0)
97 selectors.push(classes.map(c => "." + escapeCSS(c)).join(""));
98
99 // If there is a "src" attribute, specifiying a URL that we can't block,
100 // generate a CSS selector matching the "src" attribute
101 if (src)
102 selectors.push(escapeCSS(tagName) + "[src=" + quoteCSS(src) + "]");
103
104 // As last resort, if there is a "style" attribute, and we couldn't generate
105 // any filters so far, generate a CSS selector matching the "style" attribut e
106 if (style && selectors.length == 0 && filters.length == 0)
107 selectors.push(escapeCSS(tagName) + "[style=" + quoteCSS(style) + "]");
108
109 // Add an element hiding filter for each generated CSS selector
110 if (selectors.length > 0)
111 {
112 let domain = getDecodedHostname(baseURL).replace(/^www\./, "");
113
114 for (let selector of selectors)
115 filters.push(domain + "##" + selector);
116 }
117 }
118
142 return {filters: filters, selectors: selectors}; 119 return {filters: filters, selectors: selectors};
143 } 120 }
144 exports.composeFilters = composeFilters; 121 exports.composeFilters = composeFilters;
OLDNEW

Powered by Google App Engine
This is Rietveld