| LEFT | RIGHT |
| 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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 if (value != this._lastHit) | 427 if (value != this._lastHit) |
| 428 { | 428 { |
| 429 let oldValue = this._lastHit; | 429 let oldValue = this._lastHit; |
| 430 this._lastHit = value; | 430 this._lastHit = value; |
| 431 filterNotifier.emit("filter.lastHit", this, value, oldValue); | 431 filterNotifier.emit("filter.lastHit", this, value, oldValue); |
| 432 } | 432 } |
| 433 return this._lastHit; | 433 return this._lastHit; |
| 434 }, | 434 }, |
| 435 | 435 |
| 436 /** | 436 /** |
| 437 * Internal counter to keep track of the number of times the | |
| 438 * {@link ActiveFilter#domains} property is accessed. | |
| 439 * @type {number} | |
| 440 * @private | |
| 441 */ | |
| 442 _domainsAccessCount: 0, | |
| 443 | |
| 444 /** | |
| 445 * String that the domains property should be generated from | 437 * String that the domains property should be generated from |
| 446 * @type {?string} | 438 * @type {?string} |
| 447 */ | 439 */ |
| 448 domainSource: null, | 440 domainSource: null, |
| 449 | 441 |
| 450 /** | 442 /** |
| 451 * Separator character used in domainSource property, must be | 443 * Separator character used in domainSource property, must be |
| 452 * overridden by subclasses | 444 * overridden by subclasses |
| 453 * @type {string} | 445 * @type {string} |
| 454 */ | 446 */ |
| 455 domainSeparator: null, | 447 domainSeparator: null, |
| 456 | 448 |
| 457 /** | 449 /** |
| 458 * Map containing domains that this filter should match on/not match | 450 * Map containing domains that this filter should match on/not match |
| 459 * on or null if the filter should match on all domains | 451 * on or null if the filter should match on all domains |
| 460 * @type {?Map.<string,boolean>} | 452 * @type {?Map.<string,boolean>} |
| 461 */ | 453 */ |
| 462 get domains() | 454 get domains() |
| 463 { | 455 { |
| 464 // For some filter types this property is accessed only rarely, especially | |
| 465 // when the subscriptions are initially loaded. We defer any caching for | |
| 466 // such filters. | |
| 467 let cacheValue = ++this._domainsAccessCount > 3; | |
| 468 | |
| 469 let domains = null; | 456 let domains = null; |
| 470 | 457 |
| 471 if (this.domainSource) | 458 if (this.domainSource) |
| 472 { | 459 { |
| 460 // For some filter types this property is accessed only rarely, |
| 461 // especially when the subscriptions are initially loaded. We defer any |
| 462 // caching for such filters. |
| 463 let {cacheDomains} = this; |
| 464 |
| 473 let source = this.domainSource.toLowerCase(); | 465 let source = this.domainSource.toLowerCase(); |
| 474 | 466 |
| 475 let knownMap = knownDomainMaps.get(source); | 467 let knownMap = knownDomainMaps.get(source); |
| 476 if (knownMap) | 468 if (knownMap) |
| 477 { | 469 { |
| 478 domains = knownMap; | 470 domains = knownMap; |
| 479 } | 471 } |
| 480 else | 472 else |
| 481 { | 473 { |
| 482 let list = source.split(this.domainSeparator); | 474 let list = source.split(this.domainSeparator); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 509 if (!domains) | 501 if (!domains) |
| 510 domains = new Map(); | 502 domains = new Map(); |
| 511 | 503 |
| 512 domains.set(domain, include); | 504 domains.set(domain, include); |
| 513 } | 505 } |
| 514 | 506 |
| 515 if (domains) | 507 if (domains) |
| 516 domains.set("", !hasIncludes); | 508 domains.set("", !hasIncludes); |
| 517 } | 509 } |
| 518 | 510 |
| 519 if (!domains || cacheValue) | 511 if (!domains || cacheDomains) |
| 520 knownDomainMaps.set(source, domains); | 512 knownDomainMaps.set(source, domains); |
| 521 } | 513 } |
| 522 | 514 |
| 523 if (!domains || cacheValue) | 515 if (!domains || cacheDomains) |
| 516 { |
| 524 this.domainSource = null; | 517 this.domainSource = null; |
| 525 } | 518 Object.defineProperty(this, "domains", {value: domains}); |
| 526 | 519 } |
| 527 if (!domains || cacheValue) | 520 } |
| 528 Object.defineProperty(this, "domains", {value: domains}); | |
| 529 | 521 |
| 530 return domains; | 522 return domains; |
| 531 }, | 523 }, |
| 524 |
| 525 /** |
| 526 * Whether the value of {@link ActiveFilter#domains} should be cached. |
| 527 * Defaults to <code>true</code>, but may be overridden by subclasses that |
| 528 * don't want the value to be cached (for better memory usage). |
| 529 * @type {boolean} |
| 530 * @protected |
| 531 */ |
| 532 cacheDomains: true, |
| 532 | 533 |
| 533 /** | 534 /** |
| 534 * Array containing public keys of websites that this filter should apply to | 535 * Array containing public keys of websites that this filter should apply to |
| 535 * @type {?string[]} | 536 * @type {?string[]} |
| 536 */ | 537 */ |
| 537 sitekeys: null, | 538 sitekeys: null, |
| 538 | 539 |
| 539 /** | 540 /** |
| 540 * Checks whether this filter is active on a domain. | 541 * Checks whether this filter is active on a domain. |
| 541 * @param {string} [docDomain] domain name of the document that loads the URL | 542 * @param {string} [docDomain] domain name of the document that loads the URL |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 if (contentType == null) | 852 if (contentType == null) |
| 852 ({contentType} = RegExpFilter.prototype); | 853 ({contentType} = RegExpFilter.prototype); |
| 853 contentType &= ~type; | 854 contentType &= ~type; |
| 854 } | 855 } |
| 855 else | 856 else |
| 856 { | 857 { |
| 857 contentType |= type; | 858 contentType |= type; |
| 858 | 859 |
| 859 if (type == RegExpFilter.typeMap.CSP) | 860 if (type == RegExpFilter.typeMap.CSP) |
| 860 { | 861 { |
| 861 if (!value) | 862 if (blocking && !value) |
| 862 return new InvalidFilter(origText, "filter_invalid_csp"); | 863 return new InvalidFilter(origText, "filter_invalid_csp"); |
| 863 csp = value; | 864 csp = value; |
| 864 } | 865 } |
| 865 } | 866 } |
| 866 } | 867 } |
| 867 else | 868 else |
| 868 { | 869 { |
| 869 switch (option.toLowerCase()) | 870 switch (option.toLowerCase()) |
| 870 { | 871 { |
| 871 case "match-case": | 872 case "match-case": |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 * @augments ContentFilter | 1164 * @augments ContentFilter |
| 1164 */ | 1165 */ |
| 1165 function ElemHideBase(text, domains, selector) | 1166 function ElemHideBase(text, domains, selector) |
| 1166 { | 1167 { |
| 1167 ContentFilter.call(this, text, domains, selector); | 1168 ContentFilter.call(this, text, domains, selector); |
| 1168 } | 1169 } |
| 1169 exports.ElemHideBase = ElemHideBase; | 1170 exports.ElemHideBase = ElemHideBase; |
| 1170 | 1171 |
| 1171 ElemHideBase.prototype = extend(ContentFilter, { | 1172 ElemHideBase.prototype = extend(ContentFilter, { |
| 1172 /** | 1173 /** |
| 1174 * @see ActiveFilter#domains |
| 1175 * @type {?Map.<string,boolean>} |
| 1176 */ |
| 1177 get domains() |
| 1178 { |
| 1179 let {get} = Object.getOwnPropertyDescriptor(ActiveFilter.prototype, |
| 1180 "domains"); |
| 1181 let value = get.call(this); |
| 1182 this.cacheDomains = true; |
| 1183 return value; |
| 1184 }, |
| 1185 |
| 1186 /** |
| 1187 * Initially <code>false</code>, but set to <code>true</code> after |
| 1188 * {@link ActiveFilter#domains} has been accessed once. |
| 1189 * @see ActiveFilter#cacheDomains |
| 1190 * @type {boolean} |
| 1191 * @protected |
| 1192 */ |
| 1193 cacheDomains: false, |
| 1194 |
| 1195 /** |
| 1173 * CSS selector for the HTML elements that should be hidden | 1196 * CSS selector for the HTML elements that should be hidden |
| 1174 * @type {string} | 1197 * @type {string} |
| 1175 */ | 1198 */ |
| 1176 get selector() | 1199 get selector() |
| 1177 { | 1200 { |
| 1178 // Braces are being escaped to prevent CSS rule injection. | 1201 // Braces are being escaped to prevent CSS rule injection. |
| 1179 return this.body.replace("{", "\\7B ").replace("}", "\\7D "); | 1202 return this.body.replace("{", "\\7B ").replace("}", "\\7D "); |
| 1180 } | 1203 } |
| 1181 }); | 1204 }); |
| 1182 | 1205 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 | 1276 |
| 1254 /** | 1277 /** |
| 1255 * Script that should be executed | 1278 * Script that should be executed |
| 1256 * @type {string} | 1279 * @type {string} |
| 1257 */ | 1280 */ |
| 1258 get script() | 1281 get script() |
| 1259 { | 1282 { |
| 1260 return this.body; | 1283 return this.body; |
| 1261 } | 1284 } |
| 1262 }); | 1285 }); |
| LEFT | RIGHT |