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

Side by Side Diff: lib/elemHide.js

Issue 29356018: Issue 4450 - Prevent ElemHide filters with empty domains (Closed)
Patch Set: Created Oct. 5, 2016, 2:24 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
« no previous file with comments | « no previous file | lib/filterClasses.js » ('j') | lib/filterClasses.js » ('J')
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
(...skipping 25 matching lines...) Expand all
36 var keyByFilter = Object.create(null); 36 var keyByFilter = Object.create(null);
37 37
38 /** 38 /**
39 * Nested lookup table, filter (or false if inactive) by filter key by domain. 39 * 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.) 40 * (Only contains filters that aren't unconditionally matched for all domains.)
41 * @type Object 41 * @type Object
42 */ 42 */
43 var filtersByDomain = Object.create(null); 43 var filtersByDomain = Object.create(null);
44 44
45 /** 45 /**
46 * Lookup table, filter keys by selector. (Only contains filters that have a 46 * Lookup table, filter key by selector. (Only used for selectors that are
47 * selector that is unconditionally matched for all domains.) 47 * unconditionally matched for all domains.)
48 */ 48 */
49 var filterKeysBySelector = Object.create(null); 49 var filterKeyBySelector = Object.create(null);
50 50
51 /** 51 /**
52 * This array caches the keys of filterKeysBySelector table (selectors which 52 * 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 53 * unconditionally apply on all domains). It will be null if the cache needs to
54 * be rebuilt. 54 * be rebuilt.
55 */ 55 */
56 var unconditionalSelectors = null; 56 var unconditionalSelectors = null;
57 57
58 /** 58 /**
59 * This array caches the values of filterKeysBySelector table (filterIds for 59 * This array caches the values of filterKeyBySelector table (filterIds for
60 * selectors which unconditionally apply on all domains). It will be null if the 60 * selectors which unconditionally apply on all domains). It will be null if the
61 * cache needs to be rebuilt. Note: Only the first filter key for each selector 61 * cache needs to be rebuilt.
62 * is cached.
63 */ 62 */
64 var unconditionalFilterKeys = null; 63 var unconditionalFilterKeys = null;
65 64
66 /** 65 /**
67 * Object to be used instead when a filter has a blank domains property. 66 * Object to be used instead when a filter has a blank domains property.
68 */ 67 */
69 var defaultDomains = Object.create(null); 68 var defaultDomains = Object.create(null);
70 defaultDomains[""] = true; 69 defaultDomains[""] = true;
71 70
72 /** 71 /**
(...skipping 15 matching lines...) Expand all
88 var ElemHide = exports.ElemHide = 87 var ElemHide = exports.ElemHide =
89 { 88 {
90 /** 89 /**
91 * Removes all known filters 90 * Removes all known filters
92 */ 91 */
93 clear: function() 92 clear: function()
94 { 93 {
95 filterByKey = []; 94 filterByKey = [];
96 keyByFilter = Object.create(null); 95 keyByFilter = Object.create(null);
97 filtersByDomain = Object.create(null); 96 filtersByDomain = Object.create(null);
98 filterKeysBySelector = Object.create(null); 97 filterKeyBySelector = Object.create(null);
99 unconditionalSelectors = unconditionalFilterKeys = null; 98 unconditionalSelectors = unconditionalFilterKeys = null;
100 knownExceptions = Object.create(null); 99 knownExceptions = Object.create(null);
101 exceptions = Object.create(null); 100 exceptions = Object.create(null);
102 FilterNotifier.emit("elemhideupdate"); 101 FilterNotifier.emit("elemhideupdate");
103 }, 102 },
104 103
105 _addToFiltersByDomain: function(key, filter) 104 _addToFiltersByDomain: function(key, filter)
106 { 105 {
107 let domains = filter.domains || defaultDomains; 106 let domains = filter.domains || defaultDomains;
108 for (let domain in domains) 107 for (let domain in domains)
(...skipping 21 matching lines...) Expand all
130 return; 129 return;
131 130
132 let selector = filter.selector; 131 let selector = filter.selector;
133 if (!(selector in exceptions)) 132 if (!(selector in exceptions))
134 exceptions[selector] = []; 133 exceptions[selector] = [];
135 exceptions[selector].push(filter); 134 exceptions[selector].push(filter);
136 135
137 // If this is the first exception for a previously unconditionally 136 // If this is the first exception for a previously unconditionally
138 // 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
139 // lookups. 138 // lookups.
140 let filterKeys = filterKeysBySelector[selector]; 139 let filterKey = filterKeyBySelector[selector];
141 if (filterKeys) 140 if (filterKey)
142 { 141 {
143 for (let filterKey of filterKeys) 142 this._addToFiltersByDomain(filterKey, filterByKey[filterKey]);
144 this._addToFiltersByDomain(filterKey, filterByKey[filterKey]); 143 delete filterKeyBySelector[selector];
145 delete filterKeysBySelector[selector];
146 unconditionalSelectors = unconditionalFilterKeys = null; 144 unconditionalSelectors = unconditionalFilterKeys = null;
147 } 145 }
148 146
149 knownExceptions[filter.text] = true; 147 knownExceptions[filter.text] = true;
150 } 148 }
151 else 149 else
152 { 150 {
153 if (filter.text in keyByFilter) 151 if (filter.text in keyByFilter)
154 return; 152 return;
155 153
156 let key = filterByKey.push(filter) - 1; 154 let key = filterByKey.push(filter) - 1;
157 keyByFilter[filter.text] = key; 155 keyByFilter[filter.text] = key;
158 156
159 if (!(filter.domains || filter.selector in exceptions)) 157 if (!(filter.domains || filter.selector in exceptions))
160 { 158 {
161 // The new filter's selector is unconditionally applied to all domains 159 // The new filter's selector is unconditionally applied to all domains
162 let filterKeys = filterKeysBySelector[filter.selector]; 160 filterKeyBySelector[filter.selector] = key;
163 if (filterKeys) 161 unconditionalSelectors = unconditionalFilterKeys = null;
164 {
165 filterKeys.push(key);
166 }
167 else
168 {
169 filterKeysBySelector[filter.selector] = [key];
170 unconditionalSelectors = unconditionalFilterKeys = null;
171 }
172 } 162 }
173 else 163 else
174 { 164 {
175 // The new filter's selector only applies to some domains 165 // The new filter's selector only applies to some domains
176 this._addToFiltersByDomain(key, filter); 166 this._addToFiltersByDomain(key, filter);
177 } 167 }
178 } 168 }
179 169
180 FilterNotifier.emit("elemhideupdate"); 170 FilterNotifier.emit("elemhideupdate");
181 }, 171 },
182 172
183 _removeFilterKey: function(key, filter) 173 _removeFilterKey: function(key, filter)
184 { 174 {
185 let filterKeys = filterKeysBySelector[filter.selector]; 175 if (filterKeyBySelector[filter.selector] == key)
186 if (filterKeys)
187 { 176 {
188 let index = filterKeys.indexOf(key); 177 delete filterKeyBySelector[filter.selector];
189 if (index >= 0) 178 unconditionalSelectors = unconditionalFilterKeys = null;
190 { 179 return;
191 if (filterKeys.length > 1)
192 {
193 filterKeys.splice(index, 1);
194 if (index == 0)
195 unconditionalFilterKeys = null;
196 }
197 else
198 {
199 delete filterKeysBySelector[filter.selector];
200 unconditionalSelectors = unconditionalFilterKeys = null;
201 }
202 return;
203 }
204 } 180 }
205 181
206 // We haven't found this filter in unconditional filters, look in 182 // We haven't found this filter in unconditional filters, look in
207 // filtersByDomain. 183 // filtersByDomain.
208 let domains = filter.domains || defaultDomains; 184 let domains = filter.domains || defaultDomains;
209 for (let domain in domains) 185 for (let domain in domains)
210 { 186 {
211 let filters = filtersByDomain[domain]; 187 let filters = filtersByDomain[domain];
212 if (filters) 188 if (filters)
213 delete filters[key]; 189 delete filters[key];
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 return domains; 273 return domains;
298 }, 274 },
299 275
300 /** 276 /**
301 * Returns a list of selectors that apply on each website unconditionally. 277 * Returns a list of selectors that apply on each website unconditionally.
302 * @returns {String[]} 278 * @returns {String[]}
303 */ 279 */
304 getUnconditionalSelectors: function() 280 getUnconditionalSelectors: function()
305 { 281 {
306 if (!unconditionalSelectors) 282 if (!unconditionalSelectors)
307 unconditionalSelectors = Object.keys(filterKeysBySelector); 283 unconditionalSelectors = Object.keys(filterKeyBySelector);
308 return unconditionalSelectors.slice(); 284 return unconditionalSelectors.slice();
309 }, 285 },
310 286
311 /** 287 /**
312 * Returns a list of filter keys for selectors which apply to all websites 288 * Returns a list of filter keys for selectors which apply to all websites
313 * without exception. 289 * without exception.
314 * @returns {Number[]} 290 * @returns {Number[]}
315 */ 291 */
316 getUnconditionalFilterKeys: function() 292 getUnconditionalFilterKeys: function()
317 { 293 {
318 if (!unconditionalFilterKeys) 294 if (!unconditionalFilterKeys)
319 { 295 {
320 let selectors = this.getUnconditionalSelectors(); 296 let selectors = this.getUnconditionalSelectors();
321 unconditionalFilterKeys = []; 297 unconditionalFilterKeys = [];
322 for (let selector of selectors) 298 for (let selector of selectors)
323 unconditionalFilterKeys.push(filterKeysBySelector[selector][0]); 299 unconditionalFilterKeys.push(filterKeyBySelector[selector]);
324 } 300 }
325 return unconditionalFilterKeys.slice(); 301 return unconditionalFilterKeys.slice();
326 }, 302 },
327 303
328 304
329 /** 305 /**
330 * Constant used by getSelectorsForDomain to return all selectors applying to 306 * Constant used by getSelectorsForDomain to return all selectors applying to
331 * a particular hostname. 307 * a particular hostname.
332 */ 308 */
333 ALL_MATCHING: 0, 309 ALL_MATCHING: 0,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 let nextDot = currentDomain.indexOf("."); 382 let nextDot = currentDomain.indexOf(".");
407 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1); 383 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
408 } 384 }
409 385
410 if (provideFilterKeys) 386 if (provideFilterKeys)
411 return [selectors, filterKeys]; 387 return [selectors, filterKeys];
412 else 388 else
413 return selectors; 389 return selectors;
414 } 390 }
415 }; 391 };
OLDNEW
« no previous file with comments | « no previous file | lib/filterClasses.js » ('j') | lib/filterClasses.js » ('J')

Powered by Google App Engine
This is Rietveld