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

Side by Side Diff: lib/elemHide.js

Issue 29987596: Issue 7244 - Maintain cache of domain-specific style sheets (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created Jan. 23, 2019, 4:25 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 | « 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-present eyeo GmbH 3 * Copyright (C) 2006-present 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 16 matching lines...) Expand all
27 /** 27 /**
28 * The maximum number of selectors in a CSS rule. This is used by 28 * The maximum number of selectors in a CSS rule. This is used by
29 * <code>{@link createStyleSheet}</code> to split up a long list of selectors 29 * <code>{@link createStyleSheet}</code> to split up a long list of selectors
30 * into multiple rules. 30 * into multiple rules.
31 * @const {number} 31 * @const {number}
32 * @default 32 * @default
33 */ 33 */
34 const selectorGroupSize = 1024; 34 const selectorGroupSize = 1024;
35 35
36 /** 36 /**
37 * The maximum number of entries to keep in
38 * <code>{@link styleSheetCache}</code>.
39 */
40 const maxStyleSheetCacheEntries = 100;
41
42 /**
37 * Lookup table, active flag, by filter by domain. 43 * Lookup table, active flag, by filter by domain.
38 * (Only contains filters that aren't unconditionally matched for all domains.) 44 * (Only contains filters that aren't unconditionally matched for all domains.)
39 * @type {Map.<string,Map.<Filter,boolean>>} 45 * @type {Map.<string,Map.<Filter,boolean>>}
40 */ 46 */
41 let filtersByDomain = new Map(); 47 let filtersByDomain = new Map();
42 48
43 /** 49 /**
44 * Lookup table, filter by selector. (Only used for selectors that are 50 * Lookup table, filter by selector. (Only used for selectors that are
45 * unconditionally matched for all domains.) 51 * unconditionally matched for all domains.)
46 * @type {Map.<string,Filter>} 52 * @type {Map.<string,Filter>}
(...skipping 18 matching lines...) Expand all
65 /** 71 /**
66 * The common style sheet that applies on all unknown domains. This is a 72 * The common style sheet that applies on all unknown domains. This is a
67 * concatenation of the default style sheet and an additional style sheet based 73 * concatenation of the default style sheet and an additional style sheet based
68 * on selectors from all generic filters that are not in the 74 * on selectors from all generic filters that are not in the
69 * <code>{@link unconditionalSelectors}</code> list. 75 * <code>{@link unconditionalSelectors}</code> list.
70 * @type {?string} 76 * @type {?string}
71 */ 77 */
72 let commonStyleSheet = null; 78 let commonStyleSheet = null;
73 79
74 /** 80 /**
81 * Cache of generated domain-specific style sheets. This contains entries for
82 * only known domains. If a domain is unknown, it gets
83 * <code>{@link commonStyleSheet}</code>.
84 * @type {Map.<string,string>}
85 */
86 let styleSheetCache = new Map();
87
88 /**
75 * Map to be used instead when a filter has a blank domains property. 89 * Map to be used instead when a filter has a blank domains property.
76 * @type {Map.<string,boolean>} 90 * @type {Map.<string,boolean>}
77 * @const 91 * @const
78 */ 92 */
79 let defaultDomains = new Map([["", true]]); 93 let defaultDomains = new Map([["", true]]);
80 94
81 /** 95 /**
82 * Set containing known element hiding filters 96 * Set containing known element hiding filters
83 * @type {Set.<ElemHideFilter>} 97 * @type {Set.<ElemHideFilter>}
84 */ 98 */
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 { 229 {
216 if (!commonStyleSheet) 230 if (!commonStyleSheet)
217 { 231 {
218 commonStyleSheet = getDefaultStyleSheet() + 232 commonStyleSheet = getDefaultStyleSheet() +
219 createStyleSheet(getConditionalSelectors("", false)); 233 createStyleSheet(getConditionalSelectors("", false));
220 } 234 }
221 235
222 return commonStyleSheet; 236 return commonStyleSheet;
223 } 237 }
224 238
239 /**
240 * Returns the domain-specific style sheet that applies on a given domain.
241 * @param {string} domain
242 * @returns {string}
243 */
244 function getDomainSpecificStyleSheet(domain)
245 {
246 let styleSheet = styleSheetCache.get(domain);
247
248 if (typeof styleSheet == "undefined")
249 {
250 styleSheet = createStyleSheet(getConditionalSelectors(domain, false));
251
252 if (styleSheetCache.size >= maxStyleSheetCacheEntries)
253 styleSheetCache.clear();
254
255 styleSheetCache.set(domain, styleSheet);
256 }
257
258 return styleSheet;
259 }
260
225 ElemHideExceptions.on("added", ({domains, selector}) => 261 ElemHideExceptions.on("added", ({domains, selector}) =>
226 { 262 {
263 styleSheetCache.clear();
227 commonStyleSheet = null; 264 commonStyleSheet = null;
228 265
229 if (domains) 266 if (domains)
230 { 267 {
231 for (let domain of domains.keys()) 268 for (let domain of domains.keys())
232 { 269 {
233 // Note: Once an exception domain is known it never becomes unknown, even 270 // Note: Once an exception domain is known it never becomes unknown, even
234 // when all the exceptions containing that domain are removed. This is a 271 // when all the exceptions containing that domain are removed. This is a
235 // best-case optimization. 272 // best-case optimization.
236 if (domain != "") 273 if (domain != "")
(...skipping 18 matching lines...) Expand all
255 * @class 292 * @class
256 */ 293 */
257 exports.ElemHide = { 294 exports.ElemHide = {
258 /** 295 /**
259 * Removes all known filters 296 * Removes all known filters
260 */ 297 */
261 clear() 298 clear()
262 { 299 {
263 commonStyleSheet = null; 300 commonStyleSheet = null;
264 301
265 for (let collection of [filtersByDomain, filterBySelector, knownFilters, 302 for (let collection of [styleSheetCache, filtersByDomain, filterBySelector,
266 knownExceptionDomains]) 303 knownFilters, knownExceptionDomains])
267 { 304 {
268 collection.clear(); 305 collection.clear();
269 } 306 }
270 307
271 unconditionalSelectors = null; 308 unconditionalSelectors = null;
272 defaultStyleSheet = null; 309 defaultStyleSheet = null;
273 310
274 filterNotifier.emit("elemhideupdate"); 311 filterNotifier.emit("elemhideupdate");
275 }, 312 },
276 313
277 /** 314 /**
278 * Add a new element hiding filter 315 * Add a new element hiding filter
279 * @param {ElemHideFilter} filter 316 * @param {ElemHideFilter} filter
280 */ 317 */
281 add(filter) 318 add(filter)
282 { 319 {
283 if (knownFilters.has(filter)) 320 if (knownFilters.has(filter))
284 return; 321 return;
285 322
323 styleSheetCache.clear();
286 commonStyleSheet = null; 324 commonStyleSheet = null;
287 325
288 let {domains, selector} = filter; 326 let {domains, selector} = filter;
289 327
290 if (!(domains || ElemHideExceptions.hasExceptions(selector))) 328 if (!(domains || ElemHideExceptions.hasExceptions(selector)))
291 { 329 {
292 // The new filter's selector is unconditionally applied to all domains 330 // The new filter's selector is unconditionally applied to all domains
293 filterBySelector.set(selector, filter); 331 filterBySelector.set(selector, filter);
294 unconditionalSelectors = null; 332 unconditionalSelectors = null;
295 defaultStyleSheet = null; 333 defaultStyleSheet = null;
(...skipping 10 matching lines...) Expand all
306 344
307 /** 345 /**
308 * Removes an element hiding filter 346 * Removes an element hiding filter
309 * @param {ElemHideFilter} filter 347 * @param {ElemHideFilter} filter
310 */ 348 */
311 remove(filter) 349 remove(filter)
312 { 350 {
313 if (!knownFilters.has(filter)) 351 if (!knownFilters.has(filter))
314 return; 352 return;
315 353
354 styleSheetCache.clear();
316 commonStyleSheet = null; 355 commonStyleSheet = null;
317 356
318 let {selector} = filter; 357 let {selector} = filter;
319 358
320 // Unconditially applied element hiding filters 359 // Unconditially applied element hiding filters
321 if (filterBySelector.get(selector) == filter) 360 if (filterBySelector.get(selector) == filter)
322 { 361 {
323 filterBySelector.delete(selector); 362 filterBySelector.delete(selector);
324 unconditionalSelectors = null; 363 unconditionalSelectors = null;
325 defaultStyleSheet = null; 364 defaultStyleSheet = null;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 selectors = getConditionalSelectors(knownSuffix, false); 428 selectors = getConditionalSelectors(knownSuffix, false);
390 code = knownSuffix == "" ? getCommonStyleSheet() : 429 code = knownSuffix == "" ? getCommonStyleSheet() :
391 (getDefaultStyleSheet() + createStyleSheet(selectors)); 430 (getDefaultStyleSheet() + createStyleSheet(selectors));
392 431
393 selectors = getUnconditionalSelectors().concat(selectors); 432 selectors = getUnconditionalSelectors().concat(selectors);
394 } 433 }
395 else 434 else
396 { 435 {
397 code = knownSuffix == "" ? getCommonStyleSheet() : 436 code = knownSuffix == "" ? getCommonStyleSheet() :
398 (getDefaultStyleSheet() + 437 (getDefaultStyleSheet() +
399 createStyleSheet(getConditionalSelectors(knownSuffix, 438 getDomainSpecificStyleSheet(knownSuffix));
400 false)));
401 } 439 }
402 } 440 }
403 441
404 return {code, selectors: includeSelectors ? selectors : null}; 442 return {code, selectors: includeSelectors ? selectors : null};
405 } 443 }
406 }; 444 };
407 445
408 /** 446 /**
409 * Yields rules from a style sheet returned by 447 * Yields rules from a style sheet returned by
410 * <code>{@link createStyleSheet}</code>. 448 * <code>{@link createStyleSheet}</code>.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 { 517 {
480 let styleSheet = ""; 518 let styleSheet = "";
481 519
482 for (let selectorGroup of splitSelectors(selectors)) 520 for (let selectorGroup of splitSelectors(selectors))
483 styleSheet += createRule(selectorGroup); 521 styleSheet += createRule(selectorGroup);
484 522
485 return styleSheet; 523 return styleSheet;
486 } 524 }
487 525
488 exports.createStyleSheet = createStyleSheet; 526 exports.createStyleSheet = createStyleSheet;
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