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

Side by Side Diff: lib/elemHide.js

Issue 4529242486341632: Issue 235 - Improved performance of ElemHide.getSelectorsForDomain() (Closed)
Patch Set: Fixed domain logic and addressed comments Created March 12, 2015, 3:57 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 | no next file » | 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-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
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 */ 52 */
53 let exceptions = Object.create(null); 53 let exceptions = Object.create(null);
54 54
55 /** 55 /**
56 * Currently applied stylesheet URL 56 * Currently applied stylesheet URL
57 * @type nsIURI 57 * @type nsIURI
58 */ 58 */
59 let styleURL = null; 59 let styleURL = null;
60 60
61 /** 61 /**
62 * Lookup table, blocking filters by domain which they are applied to
63 * @type Object
64 */
65 let filtersByDomain = Object.create(null);
66
67 /**
68 * Indicates whether stylesheets can be used for element hiding
69 * @type Boolean
70 */
71 let canUseStylesheets = ("nsIStyleSheetService" in Ci);
72
73 /**
62 * Element hiding component 74 * Element hiding component
63 * @class 75 * @class
64 */ 76 */
65 let ElemHide = exports.ElemHide = 77 let ElemHide = exports.ElemHide =
66 { 78 {
67 /** 79 /**
68 * Indicates whether filters have been added or removed since the last apply() call. 80 * Indicates whether filters have been added or removed since the last apply() call.
69 * @type Boolean 81 * @type Boolean
70 */ 82 */
71 isDirty: false, 83 isDirty: false,
(...skipping 26 matching lines...) Expand all
98 110
99 /** 111 /**
100 * Removes all known filters 112 * Removes all known filters
101 */ 113 */
102 clear: function() 114 clear: function()
103 { 115 {
104 filterByKey = Object.create(null); 116 filterByKey = Object.create(null);
105 keyByFilter = Object.create(null); 117 keyByFilter = Object.create(null);
106 knownExceptions = Object.create(null); 118 knownExceptions = Object.create(null);
107 exceptions = Object.create(null); 119 exceptions = Object.create(null);
120 filtersByDomain = Object.create(null);
108 ElemHide.isDirty = false; 121 ElemHide.isDirty = false;
109 ElemHide.unapply(); 122 ElemHide.unapply();
110 }, 123 },
111 124
112 /** 125 /**
113 * Add a new element hiding filter 126 * Add a new element hiding filter
114 * @param {ElemHideFilter} filter 127 * @param {ElemHideFilter} filter
115 */ 128 */
116 add: function(filter) 129 add: function(filter)
117 { 130 {
118 if (filter instanceof ElemHideException) 131 if (filter instanceof ElemHideException)
119 { 132 {
120 if (filter.text in knownExceptions) 133 if (filter.text in knownExceptions)
121 return; 134 return;
122 135
123 let selector = filter.selector; 136 let selector = filter.selector;
124 if (!(selector in exceptions)) 137 if (!(selector in exceptions))
125 exceptions[selector] = []; 138 exceptions[selector] = [];
126 exceptions[selector].push(filter); 139 exceptions[selector].push(filter);
127 knownExceptions[filter.text] = true; 140 knownExceptions[filter.text] = true;
128 } 141 }
129 else 142 else
130 { 143 {
131 if (filter.text in keyByFilter) 144 if (filter.text in keyByFilter)
132 return; 145 return;
133 146
147 if (!canUseStylesheets)
148 {
149 let domains = filter.domains;
150 if (domains === null)
151 {
152 domains = Object.create(null);
153 domains[""] = true;
154 }
155
156 for (let domain in domains)
157 {
158 if (!(domain in filtersByDomain))
159 {
160 filtersByDomain[domain] = Object.create(null);
161 filtersByDomain[domain].$length = 0;
162 }
163
164 filtersByDomain[domain][filter.text] = domains[domain];
165 filtersByDomain[domain].$length++;
166 }
167 }
168
134 let key; 169 let key;
135 do { 170 do {
136 key = Math.random().toFixed(15).substr(5); 171 key = Math.random().toFixed(15).substr(5);
137 } while (key in filterByKey); 172 } while (key in filterByKey);
138 173
139 filterByKey[key] = filter; 174 filterByKey[key] = filter;
140 keyByFilter[filter.text] = key; 175 keyByFilter[filter.text] = key;
141 ElemHide.isDirty = true; 176 ElemHide.isDirty = true;
142 } 177 }
143 }, 178 },
(...skipping 13 matching lines...) Expand all
157 let index = list.indexOf(filter); 192 let index = list.indexOf(filter);
158 if (index >= 0) 193 if (index >= 0)
159 list.splice(index, 1); 194 list.splice(index, 1);
160 delete knownExceptions[filter.text]; 195 delete knownExceptions[filter.text];
161 } 196 }
162 else 197 else
163 { 198 {
164 if (!(filter.text in keyByFilter)) 199 if (!(filter.text in keyByFilter))
165 return; 200 return;
166 201
202 if (!canUseStylesheets)
203 {
204 let domains = filter.domains;
205 if (!domains)
206 {
207 domains = Object.create(null);
208 domains[""] = true;
209 }
210
211 for (let domain in domains)
212 {
213 if (domain in filtersByDomain && filter.text in filtersByDomain[domain ])
214 {
215 delete filtersByDomain[domain][filter.text];
216 if (!--filtersByDomain[domain].$length)
217 delete filtersByDomain[domain];
218 }
219 }
220 }
221
167 let key = keyByFilter[filter.text]; 222 let key = keyByFilter[filter.text];
168 delete filterByKey[key]; 223 delete filterByKey[key];
169 delete keyByFilter[filter.text]; 224 delete keyByFilter[filter.text];
170 ElemHide.isDirty = true; 225 ElemHide.isDirty = true;
171 } 226 }
172 }, 227 },
173 228
174 /** 229 /**
175 * Checks whether an exception rule is registered for a filter on a particular 230 * Checks whether an exception rule is registered for a filter on a particular
176 * domain. 231 * domain.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 420
366 /** 421 /**
367 * Retrieves an element hiding filter by the corresponding protocol key 422 * Retrieves an element hiding filter by the corresponding protocol key
368 */ 423 */
369 getFilterByKey: function(/**String*/ key) /**Filter*/ 424 getFilterByKey: function(/**String*/ key) /**Filter*/
370 { 425 {
371 return (key in filterByKey ? filterByKey[key] : null); 426 return (key in filterByKey ? filterByKey[key] : null);
372 }, 427 },
373 428
374 /** 429 /**
375 * Returns a list of all selectors active on a particular domain (currently 430 * Returns a list of all selectors active on a particular domain (it cannot
376 * used only in Chrome, Opera and Safari). 431 * be used in Firefox).
377 */ 432 */
378 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly) 433 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
379 { 434 {
380 let result = []; 435 if (canUseStylesheets)
381 for (let key in filterByKey) 436 throw new Error("Use of getSelectorsForDomain is limited to platforms whic h cannot inject stylesheets");
437
438 let selectors = [];
439 domain = domain.toUpperCase();
440
441 if (!specificOnly)
382 { 442 {
383 let filter = filterByKey[key]; 443 let filterTexts = filtersByDomain[""];
384 if (specificOnly && (!filter.domains || filter.domains[""])) 444 if (filterTexts)
385 continue; 445 {
446 for (let filterText in filterTexts)
447 {
448 if (filterTexts[filterText] && filterText != "$length")
449 {
450 let filter = Filter.fromText(filterText);
451 if (!this.getException(filter, domain))
452 selectors[selectors.length] = filter.selector;
453 }
454 }
455 }
456 }
Wladimir Palant 2015/06/05 21:58:54 This block duplicates the logic below unnecessaril
Thomas Greiner 2015/06/23 13:28:40 Done.
386 457
387 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) 458 let ignorableFilters = [];
Wladimir Palant 2015/06/05 21:58:54 Use an object here rather than an array, given tha
Thomas Greiner 2015/06/23 13:28:40 Done.
388 result.push(filter.selector); 459 while (true)
460 {
461 if (domain && domain in filtersByDomain)
462 {
463 let filterTexts = filtersByDomain[domain];
464 for (let filterText in filterTexts)
465 {
466 if (ignorableFilters.indexOf(filterText) > -1)
Wladimir Palant 2015/06/05 21:58:54 How about checking for $length immediately? if (f
Thomas Greiner 2015/06/23 13:28:40 Done.
467 continue;
468
469 if (filterTexts[filterText])
470 {
471 if (filterText == "$length")
472 continue;
473
474 let filter = Filter.fromText(filterText);
475 if (!this.getException(filter, domain))
Wladimir Palant 2015/06/05 21:58:54 Calling Filter.fromText() here looks like unnecess
Thomas Greiner 2015/06/23 13:28:40 Done. That's an awesome tip, thanks! Note that th
476 selectors[selectors.length] = filter.selector;
Wladimir Palant 2015/06/05 21:58:54 selectors.push() please. Either way, I think this
Thomas Greiner 2015/06/23 13:28:40 Done.
477 }
478 else
479 ignorableFilters[ignorableFilters.length] = filterText;
480 }
481 }
482
483 let nextDot = domain.indexOf(".");
484 if (nextDot < 0)
485 break;
486 domain = domain.substr(nextDot + 1);
389 } 487 }
390 return result; 488
489 return selectors;
391 } 490 }
392 }; 491 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld