Left: | ||
Right: |
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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
367 { | 367 { |
368 let oldValue = this._lastHit; | 368 let oldValue = this._lastHit; |
369 this._lastHit = value; | 369 this._lastHit = value; |
370 FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue); | 370 FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue); |
371 } | 371 } |
372 return this._lastHit; | 372 return this._lastHit; |
373 }, | 373 }, |
374 | 374 |
375 /** | 375 /** |
376 * String that the domains property should be generated from | 376 * String that the domains property should be generated from |
377 * @type {string} | 377 * @type {?string} |
378 */ | 378 */ |
379 domainSource: null, | 379 domainSource: null, |
380 | 380 |
381 /** | 381 /** |
382 * Separator character used in domainSource property, must be | 382 * Separator character used in domainSource property, must be |
383 * overridden by subclasses | 383 * overridden by subclasses |
384 * @type {string} | 384 * @type {string} |
385 */ | 385 */ |
386 domainSeparator: null, | 386 domainSeparator: null, |
387 | 387 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 | 464 |
465 this.domainSource = null; | 465 this.domainSource = null; |
466 } | 466 } |
467 | 467 |
468 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); | 468 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); |
469 return this.domains; | 469 return this.domains; |
470 }, | 470 }, |
471 | 471 |
472 /** | 472 /** |
473 * Array containing public keys of websites that this filter should apply to | 473 * Array containing public keys of websites that this filter should apply to |
474 * @type {string[]} | 474 * @type {?string[]} |
475 */ | 475 */ |
476 sitekeys: null, | 476 sitekeys: null, |
477 | 477 |
478 /** | 478 /** |
479 * Checks whether this filter is active on a domain. | 479 * Checks whether this filter is active on a domain. |
480 * @param {string} docDomain domain name of the document that loads the URL | 480 * @param {string} [docDomain] domain name of the document that loads the URL |
481 * @param {string} [sitekey] public key provided by the document | 481 * @param {string} [sitekey] public key provided by the document |
482 * @return {boolean} true in case of the filter being active | 482 * @return {boolean} true in case of the filter being active |
483 */ | 483 */ |
484 isActiveOnDomain(docDomain, sitekey) | 484 isActiveOnDomain(docDomain, sitekey) |
485 { | 485 { |
486 // Sitekeys are case-sensitive so we shouldn't convert them to | 486 // Sitekeys are case-sensitive so we shouldn't convert them to |
487 // upper-case to avoid false positives here. Instead we need to | 487 // upper-case to avoid false positives here. Instead we need to |
488 // change the way filter options are parsed. | 488 // change the way filter options are parsed. |
489 if (this.sitekeys && | 489 if (this.sitekeys && |
490 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) | 490 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 contentType: 0x7FFFFFFF, | 679 contentType: 0x7FFFFFFF, |
680 /** | 680 /** |
681 * Defines whether the filter should distinguish between lower and | 681 * Defines whether the filter should distinguish between lower and |
682 * upper case letters | 682 * upper case letters |
683 * @type {boolean} | 683 * @type {boolean} |
684 */ | 684 */ |
685 matchCase: false, | 685 matchCase: false, |
686 /** | 686 /** |
687 * Defines whether the filter should apply to third-party or | 687 * Defines whether the filter should apply to third-party or |
688 * first-party content only. Can be null (apply to all content). | 688 * first-party content only. Can be null (apply to all content). |
689 * @type {boolean} | 689 * @type {?boolean} |
690 */ | 690 */ |
691 thirdParty: null, | 691 thirdParty: null, |
692 | 692 |
693 /** | 693 /** |
694 * String that the sitekey property should be generated from | 694 * String that the sitekey property should be generated from |
695 * @type {string} | 695 * @type {?string} |
696 */ | 696 */ |
697 sitekeySource: null, | 697 sitekeySource: null, |
698 | 698 |
699 /** | 699 /** |
700 * Array containing public keys of websites that this filter should apply to | 700 * @see ActiveFilter.sitekeys |
701 * @type {string[]} | |
702 */ | 701 */ |
703 get sitekeys() | 702 get sitekeys() |
704 { | 703 { |
705 // Despite this property being cached, the getter is called | 704 // Despite this property being cached, the getter is called |
706 // several times on Safari, due to WebKit bug 132872 | 705 // several times on Safari, due to WebKit bug 132872 |
707 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | 706 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); |
708 if (prop) | 707 if (prop) |
709 return prop.value; | 708 return prop.value; |
710 | 709 |
711 let sitekeys = null; | 710 let sitekeys = null; |
712 | 711 |
713 if (this.sitekeySource) | 712 if (this.sitekeySource) |
714 { | 713 { |
715 sitekeys = this.sitekeySource.split("|"); | 714 sitekeys = this.sitekeySource.split("|"); |
716 this.sitekeySource = null; | 715 this.sitekeySource = null; |
717 } | 716 } |
718 | 717 |
719 Object.defineProperty( | 718 Object.defineProperty( |
720 this, "sitekeys", {value: sitekeys, enumerable: true} | 719 this, "sitekeys", {value: sitekeys, enumerable: true} |
721 ); | 720 ); |
722 return this.sitekeys; | 721 return this.sitekeys; |
723 }, | 722 }, |
724 | 723 |
725 /** | 724 /** |
726 * Tests whether the URL matches this filter | 725 * Tests whether the URL matches this filter |
727 * @param {string} location URL to be tested | 726 * @param {string} location URL to be tested |
728 * @param {number} typeMask bitmask of content / request types to match | 727 * @param {number} typeMask bitmask of content / request types to match |
729 * @param {string} docDomain domain name of the document that loads the URL | 728 * @param {string} [docDomain] domain name of the document that loads the URL |
730 * @param {boolean} thirdParty should be true if the URL is a third-party | 729 * @param {boolean} [thirdParty] should be true if the URL is a third-party |
731 * request | 730 * request |
732 * @param {string} sitekey public key provided by the document | 731 * @param {string} [sitekey] public key provided by the document |
733 * @return {boolean} true in case of a match | 732 * @return {boolean} true in case of a match |
734 */ | 733 */ |
735 matches(location, typeMask, docDomain, thirdParty, sitekey) | 734 matches(location, typeMask, docDomain, thirdParty, sitekey) |
736 { | 735 { |
737 if (this.contentType & typeMask && | 736 if (this.contentType & typeMask && |
738 (this.thirdParty == null || this.thirdParty == thirdParty) && | 737 (this.thirdParty == null || this.thirdParty == thirdParty) && |
739 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 738 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) |
740 { | 739 { |
741 return true; | 740 return true; |
742 } | 741 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
881 RegExpFilter.typeMap.DOCUMENT | | 880 RegExpFilter.typeMap.DOCUMENT | |
882 RegExpFilter.typeMap.ELEMHIDE | | 881 RegExpFilter.typeMap.ELEMHIDE | |
883 RegExpFilter.typeMap.POPUP | | 882 RegExpFilter.typeMap.POPUP | |
884 RegExpFilter.typeMap.GENERICHIDE | | 883 RegExpFilter.typeMap.GENERICHIDE | |
885 RegExpFilter.typeMap.GENERICBLOCK); | 884 RegExpFilter.typeMap.GENERICBLOCK); |
886 | 885 |
887 /** | 886 /** |
888 * Class for blocking filters | 887 * Class for blocking filters |
889 * @param {string} text see Filter() | 888 * @param {string} text see Filter() |
890 * @param {string} regexpSource see RegExpFilter() | 889 * @param {string} regexpSource see RegExpFilter() |
891 * @param {number} contentType see RegExpFilter() | 890 * @param {number} [contentType] see RegExpFilter() |
892 * @param {boolean} matchCase see RegExpFilter() | 891 * @param {boolean} [matchCase] see RegExpFilter() |
893 * @param {string} domains see RegExpFilter() | 892 * @param {string} [domains] see RegExpFilter() |
894 * @param {boolean} thirdParty see RegExpFilter() | 893 * @param {boolean} [thirdParty] see RegExpFilter() |
895 * @param {string} sitekeys see RegExpFilter() | 894 * @param {string} [sitekeys] see RegExpFilter() |
896 * @param {boolean} collapse | 895 * @param {boolean} [collapse] |
897 * defines whether the filter should collapse blocked content, can be null | 896 * defines whether the filter should collapse blocked content, can be null |
898 * @param {string} [csp] | 897 * @param {string} [csp] |
899 * Content Security Policy to inject when the filter matches | 898 * Content Security Policy to inject when the filter matches |
900 * @param {string} [rewrite] | 899 * @param {?string} [rewrite] |
901 * The rewrite expression | 900 * The (optional) rule specifying how to rewrite the URL. See |
901 * BlockingFilter.prototype.rewrite. | |
902 * @constructor | 902 * @constructor |
903 * @augments RegExpFilter | 903 * @augments RegExpFilter |
904 */ | 904 */ |
905 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, | 905 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, |
906 thirdParty, sitekeys, collapse, csp, rewrite) | 906 thirdParty, sitekeys, collapse, csp, rewrite) |
907 { | 907 { |
908 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 908 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
909 thirdParty, sitekeys); | 909 thirdParty, sitekeys); |
910 | 910 |
911 this.collapse = collapse; | 911 this.collapse = collapse; |
912 this.csp = csp; | 912 this.csp = csp; |
913 this.rewrite = rewrite; | 913 this.rewrite = rewrite; |
914 } | 914 } |
915 exports.BlockingFilter = BlockingFilter; | 915 exports.BlockingFilter = BlockingFilter; |
916 | 916 |
917 BlockingFilter.prototype = extend(RegExpFilter, { | 917 BlockingFilter.prototype = extend(RegExpFilter, { |
918 type: "blocking", | 918 type: "blocking", |
919 | 919 |
920 /** | 920 /** |
921 * Defines whether the filter should collapse blocked content. | 921 * Defines whether the filter should collapse blocked content. |
922 * Can be null (use the global preference). | 922 * Can be null (use the global preference). |
923 * @type {boolean} | 923 * @type {?boolean} |
924 */ | 924 */ |
925 collapse: null, | 925 collapse: null, |
926 | 926 |
927 /** | 927 /** |
928 * Content Security Policy to inject for matching requests. | 928 * Content Security Policy to inject for matching requests. |
929 * @type {string} | 929 * @type {?string} |
930 */ | 930 */ |
931 csp: null, | 931 csp: null, |
932 | 932 |
933 /** | 933 /** |
934 * The rewrite expression | 934 * The rule specifying how to rewrite the URL. |
935 * @type {string} | 935 * The syntax is similar to the one of String.prototype.replace(). |
936 * @type {?string} | |
936 */ | 937 */ |
937 rewrite: null, | 938 rewrite: null, |
938 | 939 |
939 /** | 940 /** |
940 * Rewrites an URL. | 941 * Rewrites an URL. |
941 * @param {string} url the URL to rewrite | 942 * @param {string} url the URL to rewrite |
942 * @return {string} the rewritten URL, or the original in case of failure | 943 * @return {string} the rewritten URL, or the original in case of failure |
943 */ | 944 */ |
944 rewriteUrl(url) | 945 rewriteUrl(url) |
945 { | 946 { |
946 let rewritten = url.replace(this.regexp, this.rewrite); | |
947 try | 947 try |
948 { | 948 { |
949 if (new URL(rewritten).origin == new URL(url).origin) | 949 let rewrittenUrl = new URL(url.replace(this.regexp, this.rewrite), url); |
kzar
2018/05/17 12:56:06
I forgot to mention before, I thought how you did
hub
2018/05/17 12:58:39
thanks!
| |
950 return rewritten; | 950 if (rewrittenUrl.origin == new URL(url).origin) |
951 return rewrittenUrl.href; | |
951 } | 952 } |
952 catch (e) | 953 catch (e) |
953 { | 954 { |
954 } | 955 } |
955 | 956 |
956 return url; | 957 return url; |
957 } | 958 } |
958 }); | 959 }); |
959 | 960 |
960 /** | 961 /** |
961 * Class for whitelist filters | 962 * Class for whitelist filters |
962 * @param {string} text see Filter() | 963 * @param {string} text see Filter() |
963 * @param {string} regexpSource see RegExpFilter() | 964 * @param {string} regexpSource see RegExpFilter() |
964 * @param {number} contentType see RegExpFilter() | 965 * @param {number} [contentType] see RegExpFilter() |
965 * @param {boolean} matchCase see RegExpFilter() | 966 * @param {boolean} [matchCase] see RegExpFilter() |
966 * @param {string} domains see RegExpFilter() | 967 * @param {string} [domains] see RegExpFilter() |
967 * @param {boolean} thirdParty see RegExpFilter() | 968 * @param {boolean} [thirdParty] see RegExpFilter() |
968 * @param {string} sitekeys see RegExpFilter() | 969 * @param {string} [sitekeys] see RegExpFilter() |
969 * @constructor | 970 * @constructor |
970 * @augments RegExpFilter | 971 * @augments RegExpFilter |
971 */ | 972 */ |
972 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, | 973 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, |
973 thirdParty, sitekeys) | 974 thirdParty, sitekeys) |
974 { | 975 { |
975 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 976 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
976 thirdParty, sitekeys); | 977 thirdParty, sitekeys); |
977 } | 978 } |
978 exports.WhitelistFilter = WhitelistFilter; | 979 exports.WhitelistFilter = WhitelistFilter; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 domainSeparator: ",", | 1014 domainSeparator: ",", |
1014 | 1015 |
1015 /** | 1016 /** |
1016 * @see ActiveFilter.ignoreTrailingDot | 1017 * @see ActiveFilter.ignoreTrailingDot |
1017 */ | 1018 */ |
1018 ignoreTrailingDot: false, | 1019 ignoreTrailingDot: false, |
1019 | 1020 |
1020 /** | 1021 /** |
1021 * Host names or domains the filter should be restricted to (can be null for | 1022 * Host names or domains the filter should be restricted to (can be null for |
1022 * no restriction) | 1023 * no restriction) |
1023 * @type {string} | 1024 * @type {?string} |
1024 */ | 1025 */ |
1025 selectorDomains: null, | 1026 selectorDomains: null, |
1026 /** | 1027 /** |
1027 * CSS selector for the HTML elements that should be hidden | 1028 * CSS selector for the HTML elements that should be hidden |
1028 * @type {string} | 1029 * @type {string} |
1029 */ | 1030 */ |
1030 selector: null | 1031 selector: null |
1031 }); | 1032 }); |
1032 | 1033 |
1033 /** | 1034 /** |
1034 * Creates an element hiding filter from a pre-parsed text representation | 1035 * Creates an element hiding filter from a pre-parsed text representation |
1035 * | 1036 * |
1036 * @param {string} text same as in Filter() | 1037 * @param {string} text same as in Filter() |
1037 * @param {string?} domains | 1038 * @param {string} [domains] |
1038 * domains part of the text representation | 1039 * domains part of the text representation |
1039 * @param {string?} type | 1040 * @param {string} [type] |
1040 * rule type, either empty or @ (exception) or ? (emulation rule) | 1041 * rule type, either empty or @ (exception) or ? (emulation rule) |
1041 * @param {string} selector raw CSS selector | 1042 * @param {string} selector raw CSS selector |
1042 * @return {ElemHideFilter|ElemHideException| | 1043 * @return {ElemHideFilter|ElemHideException| |
1043 * ElemHideEmulationFilter|InvalidFilter} | 1044 * ElemHideEmulationFilter|InvalidFilter} |
1044 */ | 1045 */ |
1045 ElemHideBase.fromText = function(text, domains, type, selector) | 1046 ElemHideBase.fromText = function(text, domains, type, selector) |
1046 { | 1047 { |
1047 // We don't allow ElemHide filters which have any empty domains. | 1048 // We don't allow ElemHide filters which have any empty domains. |
1048 // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that | 1049 // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that |
1049 // changes this must be changed too. | 1050 // changes this must be changed too. |
(...skipping 12 matching lines...) Expand all Loading... | |
1062 | 1063 |
1063 return new ElemHideEmulationFilter(text, domains, selector); | 1064 return new ElemHideEmulationFilter(text, domains, selector); |
1064 } | 1065 } |
1065 | 1066 |
1066 return new ElemHideFilter(text, domains, selector); | 1067 return new ElemHideFilter(text, domains, selector); |
1067 }; | 1068 }; |
1068 | 1069 |
1069 /** | 1070 /** |
1070 * Class for element hiding filters | 1071 * Class for element hiding filters |
1071 * @param {string} text see Filter() | 1072 * @param {string} text see Filter() |
1072 * @param {string} domains see ElemHideBase() | 1073 * @param {string} [domains] see ElemHideBase() |
1073 * @param {string} selector see ElemHideBase() | 1074 * @param {string} selector see ElemHideBase() |
1074 * @constructor | 1075 * @constructor |
1075 * @augments ElemHideBase | 1076 * @augments ElemHideBase |
1076 */ | 1077 */ |
1077 function ElemHideFilter(text, domains, selector) | 1078 function ElemHideFilter(text, domains, selector) |
1078 { | 1079 { |
1079 ElemHideBase.call(this, text, domains, selector); | 1080 ElemHideBase.call(this, text, domains, selector); |
1080 } | 1081 } |
1081 exports.ElemHideFilter = ElemHideFilter; | 1082 exports.ElemHideFilter = ElemHideFilter; |
1082 | 1083 |
1083 ElemHideFilter.prototype = extend(ElemHideBase, { | 1084 ElemHideFilter.prototype = extend(ElemHideBase, { |
1084 type: "elemhide" | 1085 type: "elemhide" |
1085 }); | 1086 }); |
1086 | 1087 |
1087 /** | 1088 /** |
1088 * Class for element hiding exceptions | 1089 * Class for element hiding exceptions |
1089 * @param {string} text see Filter() | 1090 * @param {string} text see Filter() |
1090 * @param {string} domains see ElemHideBase() | 1091 * @param {string} [domains] see ElemHideBase() |
1091 * @param {string} selector see ElemHideBase() | 1092 * @param {string} selector see ElemHideBase() |
1092 * @constructor | 1093 * @constructor |
1093 * @augments ElemHideBase | 1094 * @augments ElemHideBase |
1094 */ | 1095 */ |
1095 function ElemHideException(text, domains, selector) | 1096 function ElemHideException(text, domains, selector) |
1096 { | 1097 { |
1097 ElemHideBase.call(this, text, domains, selector); | 1098 ElemHideBase.call(this, text, domains, selector); |
1098 } | 1099 } |
1099 exports.ElemHideException = ElemHideException; | 1100 exports.ElemHideException = ElemHideException; |
1100 | 1101 |
(...skipping 11 matching lines...) Expand all Loading... | |
1112 */ | 1113 */ |
1113 function ElemHideEmulationFilter(text, domains, selector) | 1114 function ElemHideEmulationFilter(text, domains, selector) |
1114 { | 1115 { |
1115 ElemHideBase.call(this, text, domains, selector); | 1116 ElemHideBase.call(this, text, domains, selector); |
1116 } | 1117 } |
1117 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1118 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
1118 | 1119 |
1119 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1120 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
1120 type: "elemhideemulation" | 1121 type: "elemhideemulation" |
1121 }); | 1122 }); |
LEFT | RIGHT |