OLD | NEW |
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 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 * Map containing domains that this filter should match on/not match | 491 * Map containing domains that this filter should match on/not match |
492 * on or null if the filter should match on all domains | 492 * on or null if the filter should match on all domains |
493 * @type {?Map.<string,boolean>} | 493 * @type {?Map.<string,boolean>} |
494 */ | 494 */ |
495 get domains() | 495 get domains() |
496 { | 496 { |
497 let domains = null; | 497 let domains = null; |
498 | 498 |
499 if (this.domainSource) | 499 if (this.domainSource) |
500 { | 500 { |
501 // For some filter types this property is accessed only rarely, | 501 // For most filter types this property is accessed only rarely, |
502 // especially when the subscriptions are initially loaded. We defer any | 502 // especially when the subscriptions are initially loaded. We defer any |
503 // caching for such filters. | 503 // caching by default. |
504 let {cacheDomains} = this; | 504 let cacheDomains = this._cacheDomains; |
505 | 505 |
506 let source = this.domainSource.toLowerCase(); | 506 let source = this.domainSource.toLowerCase(); |
507 | 507 |
508 let knownMap = knownDomainMaps.get(source); | 508 let knownMap = knownDomainMaps.get(source); |
509 if (knownMap) | 509 if (knownMap) |
510 { | 510 { |
511 domains = knownMap; | 511 domains = knownMap; |
512 } | 512 } |
513 else | 513 else |
514 { | 514 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 knownDomainMaps.set(source, domains); | 553 knownDomainMaps.set(source, domains); |
554 } | 554 } |
555 | 555 |
556 if (!domains || cacheDomains) | 556 if (!domains || cacheDomains) |
557 { | 557 { |
558 this.domainSource = null; | 558 this.domainSource = null; |
559 Object.defineProperty(this, "domains", {value: domains}); | 559 Object.defineProperty(this, "domains", {value: domains}); |
560 } | 560 } |
561 } | 561 } |
562 | 562 |
| 563 this._cacheDomains = true; |
| 564 |
563 return domains; | 565 return domains; |
564 }, | 566 }, |
565 | 567 |
566 /** | 568 /** |
567 * Whether the value of {@link ActiveFilter#domains} should be cached. | 569 * Whether the value of {@link ActiveFilter#domains} should be cached. |
568 * Defaults to <code>true</code>, but may be overridden by subclasses that | |
569 * don't want the value to be cached (for better memory usage). | |
570 * @type {boolean} | 570 * @type {boolean} |
571 * @protected | 571 * @private |
572 */ | 572 */ |
573 cacheDomains: true, | 573 _cacheDomains: false, |
574 | 574 |
575 /** | 575 /** |
576 * Array containing public keys of websites that this filter should apply to | 576 * Array containing public keys of websites that this filter should apply to |
577 * @type {?string[]} | 577 * @type {?string[]} |
578 */ | 578 */ |
579 sitekeys: null, | 579 sitekeys: null, |
580 | 580 |
581 /** | 581 /** |
582 * Checks whether this filter is active on a domain. | 582 * Checks whether this filter is active on a domain. |
583 * @param {string} [docDomain] domain name of the document that loads the URL | 583 * @param {string} [docDomain] domain name of the document that loads the URL |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 this.pattern = regexpSource; | 757 this.pattern = regexpSource; |
758 } | 758 } |
759 } | 759 } |
760 exports.RegExpFilter = RegExpFilter; | 760 exports.RegExpFilter = RegExpFilter; |
761 | 761 |
762 RegExpFilter.prototype = extend(ActiveFilter, { | 762 RegExpFilter.prototype = extend(ActiveFilter, { |
763 /** | 763 /** |
764 * Number of filters contained, will always be 1 (required to | 764 * Number of filters contained, will always be 1 (required to |
765 * optimize {@link Matcher}). | 765 * optimize {@link Matcher}). |
766 * @type {number} | 766 * @type {number} |
| 767 * @package |
767 */ | 768 */ |
768 size: 1, | 769 size: 1, |
769 | 770 |
770 /** | 771 /** |
771 * @see ActiveFilter.domainSeparator | 772 * @see ActiveFilter.domainSeparator |
772 */ | 773 */ |
773 domainSeparator: "|", | 774 domainSeparator: "|", |
774 | 775 |
775 /** | 776 /** |
776 * Expression from which a regular expression should be generated - | 777 * Expression from which a regular expression should be generated - |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 */ | 869 */ |
869 matches(location, typeMask, docDomain, thirdParty, sitekey) | 870 matches(location, typeMask, docDomain, thirdParty, sitekey) |
870 { | 871 { |
871 return (this.contentType & typeMask) != 0 && | 872 return (this.contentType & typeMask) != 0 && |
872 (this.thirdParty == null || this.thirdParty == thirdParty) && | 873 (this.thirdParty == null || this.thirdParty == thirdParty) && |
873 this.matchesLocation(location) && | 874 this.matchesLocation(location) && |
874 this.isActiveOnDomain(docDomain, sitekey); | 875 this.isActiveOnDomain(docDomain, sitekey); |
875 }, | 876 }, |
876 | 877 |
877 /** | 878 /** |
| 879 * Checks whether the given URL matches this filter without checking the |
| 880 * filter's domains. |
| 881 * @param {string} location |
| 882 * @param {number} typeMask |
| 883 * @param {boolean} [thirdParty] |
| 884 * @param {string} [sitekey] |
| 885 * @return {boolean} |
| 886 * @package |
| 887 */ |
| 888 matchesWithoutDomain(location, typeMask, thirdParty, sitekey) |
| 889 { |
| 890 return (this.contentType & typeMask) != 0 && |
| 891 (this.thirdParty == null || this.thirdParty == thirdParty) && |
| 892 this.matchesLocation(location) && |
| 893 (!this.sitekeys || |
| 894 (sitekey && this.sitekeys.includes(sitekey.toUpperCase()))); |
| 895 }, |
| 896 |
| 897 /** |
878 * Checks whether the given URL matches this filter's pattern. | 898 * Checks whether the given URL matches this filter's pattern. |
879 * @param {string} location The URL to check. | 899 * @param {string} location The URL to check. |
880 * @param {?string} [lowerCaseLocation] The lower-case version of the URL to | 900 * @param {?string} [lowerCaseLocation] The lower-case version of the URL to |
881 * check, for case-insensitive matching. | 901 * check, for case-insensitive matching. |
882 * @returns {boolean} <code>true</code> if the URL matches. | 902 * @returns {boolean} <code>true</code> if the URL matches. |
883 * @package | 903 * @package |
884 */ | 904 */ |
885 matchesLocation(location, lowerCaseLocation) | 905 matchesLocation(location, lowerCaseLocation) |
886 { | 906 { |
887 let {regexp} = this; | 907 let {regexp} = this; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 return this.contentType == RegExpFilter.prototype.contentType && | 944 return this.contentType == RegExpFilter.prototype.contentType && |
925 this.thirdParty == null && | 945 this.thirdParty == null && |
926 !this.domainSource && !this.sitekeySource && | 946 !this.domainSource && !this.sitekeySource && |
927 !this.domains && !this.sitekeys; | 947 !this.domains && !this.sitekeys; |
928 } | 948 } |
929 }); | 949 }); |
930 | 950 |
931 /** | 951 /** |
932 * Yields the filter itself (required to optimize {@link Matcher}). | 952 * Yields the filter itself (required to optimize {@link Matcher}). |
933 * @yields {RegExpFilter} | 953 * @yields {RegExpFilter} |
| 954 * @package |
934 */ | 955 */ |
935 RegExpFilter.prototype[Symbol.iterator] = function*() | 956 RegExpFilter.prototype[Symbol.iterator] = function*() |
936 { | 957 { |
937 yield this; | 958 yield this; |
938 }; | 959 }; |
939 | 960 |
940 /** | 961 /** |
| 962 * Yields a key-value pair consisting of the filter itself and the value |
| 963 * <code>true</code> (required to optimize {@link Matcher}). |
| 964 * @yields {Array} |
| 965 * @package |
| 966 */ |
| 967 RegExpFilter.prototype.entries = function*() |
| 968 { |
| 969 yield [this, true]; |
| 970 }; |
| 971 |
| 972 /** |
941 * Creates a RegExp filter from its text representation | 973 * Creates a RegExp filter from its text representation |
942 * @param {string} text same as in Filter() | 974 * @param {string} text same as in Filter() |
943 * @return {Filter} | 975 * @return {Filter} |
944 */ | 976 */ |
945 RegExpFilter.fromText = function(text) | 977 RegExpFilter.fromText = function(text) |
946 { | 978 { |
947 let blocking = true; | 979 let blocking = true; |
948 let origText = text; | 980 let origText = text; |
949 if (text[0] == "@" && text[1] == "@") | 981 if (text[0] == "@" && text[1] == "@") |
950 { | 982 { |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 * @augments ContentFilter | 1354 * @augments ContentFilter |
1323 */ | 1355 */ |
1324 function ElemHideBase(text, domains, selector) | 1356 function ElemHideBase(text, domains, selector) |
1325 { | 1357 { |
1326 ContentFilter.call(this, text, domains, selector); | 1358 ContentFilter.call(this, text, domains, selector); |
1327 } | 1359 } |
1328 exports.ElemHideBase = ElemHideBase; | 1360 exports.ElemHideBase = ElemHideBase; |
1329 | 1361 |
1330 ElemHideBase.prototype = extend(ContentFilter, { | 1362 ElemHideBase.prototype = extend(ContentFilter, { |
1331 /** | 1363 /** |
1332 * @see ActiveFilter#domains | |
1333 * @type {?Map.<string,boolean>} | |
1334 */ | |
1335 get domains() | |
1336 { | |
1337 let {get} = Object.getOwnPropertyDescriptor(ActiveFilter.prototype, | |
1338 "domains"); | |
1339 let value = get.call(this); | |
1340 this.cacheDomains = true; | |
1341 return value; | |
1342 }, | |
1343 | |
1344 /** | |
1345 * Initially <code>false</code>, but set to <code>true</code> after | |
1346 * {@link ActiveFilter#domains} has been accessed once. | |
1347 * @see ActiveFilter#cacheDomains | |
1348 * @type {boolean} | |
1349 * @protected | |
1350 */ | |
1351 cacheDomains: false, | |
1352 | |
1353 /** | |
1354 * CSS selector for the HTML elements that should be hidden | 1364 * CSS selector for the HTML elements that should be hidden |
1355 * @type {string} | 1365 * @type {string} |
1356 */ | 1366 */ |
1357 get selector() | 1367 get selector() |
1358 { | 1368 { |
1359 // Braces are being escaped to prevent CSS rule injection. | 1369 // Braces are being escaped to prevent CSS rule injection. |
1360 return this.body.replace("{", "\\7B ").replace("}", "\\7D "); | 1370 return this.body.replace("{", "\\7B ").replace("}", "\\7D "); |
1361 } | 1371 } |
1362 }); | 1372 }); |
1363 | 1373 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 | 1444 |
1435 /** | 1445 /** |
1436 * Script that should be executed | 1446 * Script that should be executed |
1437 * @type {string} | 1447 * @type {string} |
1438 */ | 1448 */ |
1439 get script() | 1449 get script() |
1440 { | 1450 { |
1441 return this.body; | 1451 return this.body; |
1442 } | 1452 } |
1443 }); | 1453 }); |
OLD | NEW |