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

Side by Side Diff: lib/elemHide.js

Issue 29375915: Issue 4878 - Start using ESLint for adblockpluscore (Closed)
Patch Set: Rebased Created March 10, 2017, 7:02 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/downloader.js ('k') | lib/elemHideEmulation.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 "use strict";
19
18 /** 20 /**
19 * @fileOverview Element hiding implementation. 21 * @fileOverview Element hiding implementation.
20 */ 22 */
21 23
22 let {Utils} = require("utils"); 24 const {ElemHideException} = require("filterClasses");
23 let {ElemHideException} = require("filterClasses"); 25 const {FilterNotifier} = require("filterNotifier");
24 let {FilterNotifier} = require("filterNotifier");
25 26
26 /** 27 /**
27 * Lookup table, filters by their associated key 28 * Lookup table, filters by their associated key
28 * @type Object 29 * @type {Object}
29 */ 30 */
30 var filterByKey = []; 31 let filterByKey = [];
31 32
32 /** 33 /**
33 * Lookup table, keys of the filters by filter text 34 * Lookup table, keys of the filters by filter text
34 * @type Object 35 * @type {Object}
35 */ 36 */
36 var keyByFilter = Object.create(null); 37 let keyByFilter = Object.create(null);
37 38
38 /** 39 /**
39 * Nested lookup table, filter (or false if inactive) by filter key by domain. 40 * Nested lookup table, filter (or false if inactive) by filter key by domain.
40 * (Only contains filters that aren't unconditionally matched for all domains.) 41 * (Only contains filters that aren't unconditionally matched for all domains.)
41 * @type Object 42 * @type {Object}
42 */ 43 */
43 var filtersByDomain = Object.create(null); 44 let filtersByDomain = Object.create(null);
44 45
45 /** 46 /**
46 * Lookup table, filter key by selector. (Only used for selectors that are 47 * Lookup table, filter key by selector. (Only used for selectors that are
47 * unconditionally matched for all domains.) 48 * unconditionally matched for all domains.)
48 */ 49 */
49 var filterKeyBySelector = Object.create(null); 50 let filterKeyBySelector = Object.create(null);
50 51
51 /** 52 /**
52 * This array caches the keys of filterKeyBySelector table (selectors which 53 * This array caches the keys of filterKeyBySelector table (selectors which
53 * unconditionally apply on all domains). It will be null if the cache needs to 54 * unconditionally apply on all domains). It will be null if the cache needs to
54 * be rebuilt. 55 * be rebuilt.
55 */ 56 */
56 var unconditionalSelectors = null; 57 let unconditionalSelectors = null;
57 58
58 /** 59 /**
59 * This array caches the values of filterKeyBySelector table (filterIds for 60 * This array caches the values of filterKeyBySelector table (filterIds for
60 * selectors which unconditionally apply on all domains). It will be null if the 61 * selectors which unconditionally apply on all domains). It will be null if the
61 * cache needs to be rebuilt. 62 * cache needs to be rebuilt.
62 */ 63 */
63 var unconditionalFilterKeys = null; 64 let unconditionalFilterKeys = null;
64 65
65 /** 66 /**
66 * Object to be used instead when a filter has a blank domains property. 67 * Object to be used instead when a filter has a blank domains property.
67 */ 68 */
68 var defaultDomains = Object.create(null); 69 let defaultDomains = Object.create(null);
69 defaultDomains[""] = true; 70 defaultDomains[""] = true;
70 71
71 /** 72 /**
72 * Lookup table, keys are known element hiding exceptions 73 * Lookup table, keys are known element hiding exceptions
73 * @type Object 74 * @type {Object}
74 */ 75 */
75 var knownExceptions = Object.create(null); 76 let knownExceptions = Object.create(null);
76 77
77 /** 78 /**
78 * Lookup table, lists of element hiding exceptions by selector 79 * Lookup table, lists of element hiding exceptions by selector
79 * @type Object 80 * @type {Object}
80 */ 81 */
81 var exceptions = Object.create(null); 82 let exceptions = Object.create(null);
82 83
83 /** 84 /**
84 * Container for element hiding filters 85 * Container for element hiding filters
85 * @class 86 * @class
86 */ 87 */
87 var ElemHide = exports.ElemHide = 88 let ElemHide = exports.ElemHide = {
88 {
89 /** 89 /**
90 * Removes all known filters 90 * Removes all known filters
91 */ 91 */
92 clear: function() 92 clear()
93 { 93 {
94 filterByKey = []; 94 filterByKey = [];
95 keyByFilter = Object.create(null); 95 keyByFilter = Object.create(null);
96 filtersByDomain = Object.create(null); 96 filtersByDomain = Object.create(null);
97 filterKeyBySelector = Object.create(null); 97 filterKeyBySelector = Object.create(null);
98 unconditionalSelectors = unconditionalFilterKeys = null; 98 unconditionalSelectors = unconditionalFilterKeys = null;
99 knownExceptions = Object.create(null); 99 knownExceptions = Object.create(null);
100 exceptions = Object.create(null); 100 exceptions = Object.create(null);
101 FilterNotifier.emit("elemhideupdate"); 101 FilterNotifier.emit("elemhideupdate");
102 }, 102 },
103 103
104 _addToFiltersByDomain: function(key, filter) 104 _addToFiltersByDomain(key, filter)
105 { 105 {
106 let domains = filter.domains || defaultDomains; 106 let domains = filter.domains || defaultDomains;
107 for (let domain in domains) 107 for (let domain in domains)
108 { 108 {
109 let filters = filtersByDomain[domain]; 109 let filters = filtersByDomain[domain];
110 if (!filters) 110 if (!filters)
111 filters = filtersByDomain[domain] = Object.create(null); 111 filters = filtersByDomain[domain] = Object.create(null);
112 112
113 if (domains[domain]) 113 if (domains[domain])
114 filters[key] = filter; 114 filters[key] = filter;
115 else 115 else
116 filters[key] = false; 116 filters[key] = false;
117 } 117 }
118 }, 118 },
119 119
120 /** 120 /**
121 * Add a new element hiding filter 121 * Add a new element hiding filter
122 * @param {ElemHideFilter} filter 122 * @param {ElemHideFilter} filter
123 */ 123 */
124 add: function(filter) 124 add(filter)
125 { 125 {
126 if (filter instanceof ElemHideException) 126 if (filter instanceof ElemHideException)
127 { 127 {
128 if (filter.text in knownExceptions) 128 if (filter.text in knownExceptions)
129 return; 129 return;
130 130
131 let selector = filter.selector; 131 let {selector} = filter;
132 if (!(selector in exceptions)) 132 if (!(selector in exceptions))
133 exceptions[selector] = []; 133 exceptions[selector] = [];
134 exceptions[selector].push(filter); 134 exceptions[selector].push(filter);
135 135
136 // If this is the first exception for a previously unconditionally 136 // If this is the first exception for a previously unconditionally
137 // applied element hiding selector we need to take care to update the 137 // applied element hiding selector we need to take care to update the
138 // lookups. 138 // lookups.
139 let filterKey = filterKeyBySelector[selector]; 139 let filterKey = filterKeyBySelector[selector];
140 if (typeof filterKey != "undefined") 140 if (typeof filterKey != "undefined")
141 { 141 {
(...skipping 21 matching lines...) Expand all
163 else 163 else
164 { 164 {
165 // The new filter's selector only applies to some domains 165 // The new filter's selector only applies to some domains
166 this._addToFiltersByDomain(key, filter); 166 this._addToFiltersByDomain(key, filter);
167 } 167 }
168 } 168 }
169 169
170 FilterNotifier.emit("elemhideupdate"); 170 FilterNotifier.emit("elemhideupdate");
171 }, 171 },
172 172
173 _removeFilterKey: function(key, filter) 173 _removeFilterKey(key, filter)
174 { 174 {
175 if (filterKeyBySelector[filter.selector] == key) 175 if (filterKeyBySelector[filter.selector] == key)
176 { 176 {
177 delete filterKeyBySelector[filter.selector]; 177 delete filterKeyBySelector[filter.selector];
178 unconditionalSelectors = unconditionalFilterKeys = null; 178 unconditionalSelectors = unconditionalFilterKeys = null;
179 return; 179 return;
180 } 180 }
181 181
182 // We haven't found this filter in unconditional filters, look in 182 // We haven't found this filter in unconditional filters, look in
183 // filtersByDomain. 183 // filtersByDomain.
184 let domains = filter.domains || defaultDomains; 184 let domains = filter.domains || defaultDomains;
185 for (let domain in domains) 185 for (let domain in domains)
186 { 186 {
187 let filters = filtersByDomain[domain]; 187 let filters = filtersByDomain[domain];
188 if (filters) 188 if (filters)
189 delete filters[key]; 189 delete filters[key];
190 } 190 }
191 }, 191 },
192 192
193 /** 193 /**
194 * Removes an element hiding filter 194 * Removes an element hiding filter
195 * @param {ElemHideFilter} filter 195 * @param {ElemHideFilter} filter
196 */ 196 */
197 remove: function(filter) 197 remove(filter)
198 { 198 {
199 if (filter instanceof ElemHideException) 199 if (filter instanceof ElemHideException)
200 { 200 {
201 if (!(filter.text in knownExceptions)) 201 if (!(filter.text in knownExceptions))
202 return; 202 return;
203 203
204 let list = exceptions[filter.selector]; 204 let list = exceptions[filter.selector];
205 let index = list.indexOf(filter); 205 let index = list.indexOf(filter);
206 if (index >= 0) 206 if (index >= 0)
207 list.splice(index, 1); 207 list.splice(index, 1);
208 delete knownExceptions[filter.text]; 208 delete knownExceptions[filter.text];
209 } 209 }
210 else 210 else
211 { 211 {
212 if (!(filter.text in keyByFilter)) 212 if (!(filter.text in keyByFilter))
213 return; 213 return;
214 214
215 let key = keyByFilter[filter.text]; 215 let key = keyByFilter[filter.text];
216 delete filterByKey[key]; 216 delete filterByKey[key];
217 delete keyByFilter[filter.text]; 217 delete keyByFilter[filter.text];
218 this._removeFilterKey(key, filter); 218 this._removeFilterKey(key, filter);
219 } 219 }
220 220
221 FilterNotifier.emit("elemhideupdate"); 221 FilterNotifier.emit("elemhideupdate");
222 }, 222 },
223 223
224 /** 224 /**
225 * Checks whether an exception rule is registered for a filter on a particular 225 * Checks whether an exception rule is registered for a filter on a particular
226 * domain. 226 * domain.
227 * @param {Filter} filter
228 * @param {string} docDomain
229 * @return {ElemHideException}
227 */ 230 */
228 getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideE xception*/ 231 getException(filter, docDomain)
229 { 232 {
230 if (!(filter.selector in exceptions)) 233 if (!(filter.selector in exceptions))
231 return null; 234 return null;
232 235
233 let list = exceptions[filter.selector]; 236 let list = exceptions[filter.selector];
234 for (let i = list.length - 1; i >= 0; i--) 237 for (let i = list.length - 1; i >= 0; i--)
238 {
235 if (list[i].isActiveOnDomain(docDomain)) 239 if (list[i].isActiveOnDomain(docDomain))
236 return list[i]; 240 return list[i];
241 }
237 242
238 return null; 243 return null;
239 }, 244 },
240 245
241 /** 246 /**
242 * Retrieves an element hiding filter by the corresponding protocol key 247 * Retrieves an element hiding filter by the corresponding protocol key
248 * @param {number} key
249 * @return {Filter}
243 */ 250 */
244 getFilterByKey: function(/**Number*/ key) /**Filter*/ 251 getFilterByKey(key)
245 { 252 {
246 return (key in filterByKey ? filterByKey[key] : null); 253 return (key in filterByKey ? filterByKey[key] : null);
247 }, 254 },
248 255
249 /** 256 /**
250 * Returns a list of all selectors as a nested map. On first level, the keys 257 * Returns a list of all selectors as a nested map. On first level, the keys
251 * are all values of `ElemHideBase.selectorDomain` (domains on which these 258 * are all values of `ElemHideBase.selectorDomain` (domains on which these
252 * selectors should apply, ignoring exceptions). The values are maps again, 259 * selectors should apply, ignoring exceptions). The values are maps again,
253 * with the keys being selectors and values the corresponding filter keys. 260 * with the keys being selectors and values the corresponding filter keys.
254 * @returns {Map.<String,Map<String,String>>} 261 * @returns {Map.<String,Map<String,String>>}
255 */ 262 */
256 getSelectors: function() 263 getSelectors()
257 { 264 {
258 let domains = new Map(); 265 let domains = new Map();
259 for (let key in filterByKey) 266 for (let key in filterByKey)
260 { 267 {
261 let filter = filterByKey[key]; 268 let filter = filterByKey[key];
262 let selector = filter.selector; 269 if (!filter.selector)
263 if (!selector)
264 continue; 270 continue;
265 271
266 let domain = filter.selectorDomain || ""; 272 let domain = filter.selectorDomain || "";
267 273
268 if (!domains.has(domain)) 274 if (!domains.has(domain))
269 domains.set(domain, new Map()); 275 domains.set(domain, new Map());
270 domains.get(domain).set(selector, key); 276 domains.get(domain).set(filter.selector, key);
271 } 277 }
272 278
273 return domains; 279 return domains;
274 }, 280 },
275 281
276 /** 282 /**
277 * Returns a list of selectors that apply on each website unconditionally. 283 * Returns a list of selectors that apply on each website unconditionally.
278 * @returns {String[]} 284 * @returns {string[]}
279 */ 285 */
280 getUnconditionalSelectors: function() 286 getUnconditionalSelectors()
281 { 287 {
282 if (!unconditionalSelectors) 288 if (!unconditionalSelectors)
283 unconditionalSelectors = Object.keys(filterKeyBySelector); 289 unconditionalSelectors = Object.keys(filterKeyBySelector);
284 return unconditionalSelectors.slice(); 290 return unconditionalSelectors.slice();
285 }, 291 },
286 292
287 /** 293 /**
288 * Returns a list of filter keys for selectors which apply to all websites 294 * Returns a list of filter keys for selectors which apply to all websites
289 * without exception. 295 * without exception.
290 * @returns {Number[]} 296 * @returns {number[]}
291 */ 297 */
292 getUnconditionalFilterKeys: function() 298 getUnconditionalFilterKeys()
293 { 299 {
294 if (!unconditionalFilterKeys) 300 if (!unconditionalFilterKeys)
295 { 301 {
296 let selectors = this.getUnconditionalSelectors(); 302 let selectors = this.getUnconditionalSelectors();
297 unconditionalFilterKeys = []; 303 unconditionalFilterKeys = [];
298 for (let selector of selectors) 304 for (let selector of selectors)
299 unconditionalFilterKeys.push(filterKeyBySelector[selector]); 305 unconditionalFilterKeys.push(filterKeyBySelector[selector]);
300 } 306 }
301 return unconditionalFilterKeys.slice(); 307 return unconditionalFilterKeys.slice();
302 }, 308 },
(...skipping 14 matching lines...) Expand all
317 /** 323 /**
318 * Constant used by getSelectorsForDomain to return only selectors for filters 324 * Constant used by getSelectorsForDomain to return only selectors for filters
319 * which specifically match the given host name. 325 * which specifically match the given host name.
320 */ 326 */
321 SPECIFIC_ONLY: 2, 327 SPECIFIC_ONLY: 2,
322 328
323 /** 329 /**
324 * Determines from the current filter list which selectors should be applied 330 * Determines from the current filter list which selectors should be applied
325 * on a particular host name. Optionally returns the corresponding filter 331 * on a particular host name. Optionally returns the corresponding filter
326 * keys. 332 * keys.
327 * @param {String} domain 333 * @param {string} domain
328 * @param {Number} [criteria] 334 * @param {number} [criteria]
329 * One of the following: ElemHide.ALL_MATCHING, ElemHide.NO_UNCONDITIONAL or 335 * One of the following: ElemHide.ALL_MATCHING, ElemHide.NO_UNCONDITIONAL or
330 * ElemHide.SPECIFIC_ONLY. 336 * ElemHide.SPECIFIC_ONLY.
331 * @param {Boolean} [provideFilterKeys] 337 * @param {boolean} [provideFilterKeys]
332 * If true, the function will return a list of corresponding filter keys in 338 * If true, the function will return a list of corresponding filter keys in
333 * addition to selectors. 339 * addition to selectors.
334 * @returns {string[]|Array.<string[]>} 340 * @returns {string[]|Array.<string[]>}
335 * List of selectors or an array with two elements (list of selectors and 341 * List of selectors or an array with two elements (list of selectors and
336 * list of corresponding keys) if provideFilterKeys is true. 342 * list of corresponding keys) if provideFilterKeys is true.
337 */ 343 */
338 getSelectorsForDomain: function(domain, criteria, provideFilterKeys) 344 getSelectorsForDomain(domain, criteria, provideFilterKeys)
339 { 345 {
340 let filterKeys = []; 346 let filterKeys = [];
341 let selectors = []; 347 let selectors = [];
342 348
343 if (typeof criteria == "undefined") 349 if (typeof criteria == "undefined")
344 criteria = ElemHide.ALL_MATCHING; 350 criteria = ElemHide.ALL_MATCHING;
345 if (criteria < ElemHide.NO_UNCONDITIONAL) 351 if (criteria < ElemHide.NO_UNCONDITIONAL)
346 { 352 {
347 selectors = this.getUnconditionalSelectors(); 353 selectors = this.getUnconditionalSelectors();
348 if (provideFilterKeys) 354 if (provideFilterKeys)
(...skipping 29 matching lines...) Expand all
378 384
379 if (currentDomain == "") 385 if (currentDomain == "")
380 break; 386 break;
381 387
382 let nextDot = currentDomain.indexOf("."); 388 let nextDot = currentDomain.indexOf(".");
383 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1); 389 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
384 } 390 }
385 391
386 if (provideFilterKeys) 392 if (provideFilterKeys)
387 return [selectors, filterKeys]; 393 return [selectors, filterKeys];
388 else 394 return selectors;
389 return selectors;
390 } 395 }
391 }; 396 };
OLDNEW
« no previous file with comments | « lib/downloader.js ('k') | lib/elemHideEmulation.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld