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

Powered by Google App Engine
This is Rietveld