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

Delta Between Two Patch Sets: lib/filterClasses.js

Issue 29375915: Issue 4878 - Start using ESLint for adblockpluscore (Closed)
Left Patch Set: Remove shared-node-browser env and Buffer global Created Feb. 23, 2017, 10:51 a.m.
Right Patch Set: Removed unused imports Created March 15, 2017, 3:11 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « lib/events.js ('k') | lib/filterListener.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 * @type {RegExp} 93 * @type {RegExp}
94 */ 94 */
95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/; 95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/;
96 /** 96 /**
97 * Regular expression that options on a RegExp filter should match 97 * Regular expression that options on a RegExp filter should match
98 * @type {RegExp} 98 * @type {RegExp}
99 */ 99 */
100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/; 100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/;
101 101
102 /** 102 /**
103 * Creates a filter of correct type from its text representation - 103 * Creates a filter of correct type from its text representation - does the
104 * does the basic parsing and calls the right constructor then. 104 * basic parsing and calls the right constructor then.
105 * 105 *
106 * @param {string} text as in Filter() 106 * @param {string} text as in Filter()
107 * @return {Filter} 107 * @return {Filter}
108 */ 108 */
109 Filter.fromText = function(text) 109 Filter.fromText = function(text)
110 { 110 {
111 if (text in Filter.knownFilters) 111 if (text in Filter.knownFilters)
112 return Filter.knownFilters[text]; 112 return Filter.knownFilters[text];
113 113
114 let ret; 114 let ret;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // Remove line breaks and such 163 // Remove line breaks and such
164 text = text.replace(/[^\S ]/g, ""); 164 text = text.replace(/[^\S ]/g, "");
165 165
166 if (/^\s*!/.test(text)) 166 if (/^\s*!/.test(text))
167 { 167 {
168 // Don't remove spaces inside comments 168 // Don't remove spaces inside comments
169 return text.trim(); 169 return text.trim();
170 } 170 }
171 else if (Filter.elemhideRegExp.test(text)) 171 else if (Filter.elemhideRegExp.test(text))
172 { 172 {
173 // Special treatment for element hiding filters, right side is 173 // Special treatment for element hiding filters, right side is allowed to
174 // allowed to contain spaces 174 // contain spaces
175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text); 175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text);
176 return domain.replace(/\s/g, "") + separator + selector.trim(); 176 return domain.replace(/\s/g, "") + separator + selector.trim();
177 } 177 }
178 return text.replace(/\s/g, ""); 178 return text.replace(/\s/g, "");
179 }; 179 };
180 180
181 /** 181 /**
182 * @see filterToRegExp 182 * @see filterToRegExp
183 */ 183 */
184 Filter.toRegExp = filterToRegExp; 184 Filter.toRegExp = filterToRegExp;
(...skipping 17 matching lines...) Expand all
202 type: "invalid", 202 type: "invalid",
203 203
204 /** 204 /**
205 * Reason why this filter is invalid 205 * Reason why this filter is invalid
206 * @type {string} 206 * @type {string}
207 */ 207 */
208 reason: null, 208 reason: null,
209 209
210 /** 210 /**
211 * See Filter.serialize() 211 * See Filter.serialize()
212 * @param {string[]} buffer buffer to push the serialization results into 212 * @inheritdoc
213 */ 213 */
214 serialize(buffer) {} 214 serialize(buffer) {}
215 }); 215 });
216 216
217 /** 217 /**
218 * Class for comments 218 * Class for comments
219 * @param {string} text see Filter() 219 * @param {string} text see Filter()
220 * @constructor 220 * @constructor
221 * @augments Filter 221 * @augments Filter
222 */ 222 */
223 function CommentFilter(text) 223 function CommentFilter(text)
224 { 224 {
225 Filter.call(this, text); 225 Filter.call(this, text);
226 } 226 }
227 exports.CommentFilter = CommentFilter; 227 exports.CommentFilter = CommentFilter;
228 228
229 CommentFilter.prototype = extend(Filter, { 229 CommentFilter.prototype = extend(Filter, {
230 type: "comment", 230 type: "comment",
231 231
232 /** 232 /**
233 * See Filter.serialize() 233 * See Filter.serialize()
234 * @param {string[]} buffer buffer to push the serialization results into 234 * @inheritdoc
235 */ 235 */
236 serialize(buffer) {} 236 serialize(buffer) {}
237 }); 237 });
238 238
239 /** 239 /**
240 * Abstract base class for filters that can get hits 240 * Abstract base class for filters that can get hits
241 * @param {string} text see Filter() 241 * @param {string} text
242 * @param {string} [domains] Domains that the filter is restricted to 242 * see Filter()
243 * separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" 243 * @param {string} [domains]
244 * Domains that the filter is restricted to separated by domainSeparator
245 * e.g. "foo.com|bar.com|~baz.com"
244 * @constructor 246 * @constructor
245 * @augments Filter 247 * @augments Filter
246 */ 248 */
247 function ActiveFilter(text, domains) 249 function ActiveFilter(text, domains)
248 { 250 {
249 Filter.call(this, text); 251 Filter.call(this, text);
250 252
251 this.domainSource = domains; 253 this.domainSource = domains;
252 } 254 }
253 exports.ActiveFilter = ActiveFilter; 255 exports.ActiveFilter = ActiveFilter;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 if (value != this._hitCount) 291 if (value != this._hitCount)
290 { 292 {
291 let oldValue = this._hitCount; 293 let oldValue = this._hitCount;
292 this._hitCount = value; 294 this._hitCount = value;
293 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); 295 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue);
294 } 296 }
295 return this._hitCount; 297 return this._hitCount;
296 }, 298 },
297 299
298 /** 300 /**
299 * Last time the filter had a hit (in milliseconds since the 301 * Last time the filter had a hit (in milliseconds since the beginning of the
300 * beginning of the epoch) 302 * epoch)
301 * @type {number} 303 * @type {number}
302 */ 304 */
303 get lastHit() 305 get lastHit()
304 { 306 {
305 return this._lastHit; 307 return this._lastHit;
306 }, 308 },
307 set lastHit(value) 309 set lastHit(value)
308 { 310 {
309 if (value != this._lastHit) 311 if (value != this._lastHit)
310 { 312 {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 * @param {string} [sitekey] public key provided by the document 428 * @param {string} [sitekey] public key provided by the document
427 * @return {boolean} true in case of the filter being active 429 * @return {boolean} true in case of the filter being active
428 */ 430 */
429 isActiveOnDomain(docDomain, sitekey) 431 isActiveOnDomain(docDomain, sitekey)
430 { 432 {
431 // Sitekeys are case-sensitive so we shouldn't convert them to 433 // Sitekeys are case-sensitive so we shouldn't convert them to
432 // upper-case to avoid false positives here. Instead we need to 434 // upper-case to avoid false positives here. Instead we need to
433 // change the way filter options are parsed. 435 // change the way filter options are parsed.
434 if (this.sitekeys && 436 if (this.sitekeys &&
435 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) 437 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0))
438 {
436 return false; 439 return false;
440 }
437 441
438 // If no domains are set the rule matches everywhere 442 // If no domains are set the rule matches everywhere
439 if (!this.domains) 443 if (!this.domains)
440 return true; 444 return true;
441 445
442 // If the document has no host name, match only if the filter 446 // If the document has no host name, match only if the filter
443 // isn't restricted to specific domains 447 // isn't restricted to specific domains
444 if (!docDomain) 448 if (!docDomain)
445 return this.domains[""]; 449 return this.domains[""];
446 450
(...skipping 28 matching lines...) Expand all
475 docDomain = docDomain.replace(/\.+$/, ""); 479 docDomain = docDomain.replace(/\.+$/, "");
476 docDomain = docDomain.toUpperCase(); 480 docDomain = docDomain.toUpperCase();
477 481
478 for (let domain in this.domains) 482 for (let domain in this.domains)
479 { 483 {
480 if (this.domains[domain] && domain != docDomain) 484 if (this.domains[domain] && domain != docDomain)
481 { 485 {
482 if (domain.length <= docDomain.length) 486 if (domain.length <= docDomain.length)
483 return false; 487 return false;
484 488
485 let pos = domain.indexOf("." + docDomain); 489 if (!domain.endsWith("." + docDomain))
486 if (pos != domain.length - docDomain.length - 1)
487 return false; 490 return false;
488 } 491 }
489 } 492 }
490 493
491 return true; 494 return true;
492 }, 495 },
493 496
494 /** 497 /**
495 * Checks whether this filter is generic or specific 498 * Checks whether this filter is generic or specific
496 * @return {boolean} 499 * @return {boolean}
497 */ 500 */
498 isGeneric() 501 isGeneric()
499 { 502 {
500 return !(this.sitekeys && this.sitekeys.length) && 503 return !(this.sitekeys && this.sitekeys.length) &&
501 (!this.domains || this.domains[""]); 504 (!this.domains || this.domains[""]);
502 }, 505 },
503 506
504 /** 507 /**
505 * See Filter.serialize() 508 * See Filter.serialize()
506 * @param {string[]} buffer buffer to push the serialization results into 509 * @inheritdoc
507 */ 510 */
508 serialize(buffer) 511 serialize(buffer)
509 { 512 {
510 if (this._disabled || this._hitCount || this._lastHit) 513 if (this._disabled || this._hitCount || this._lastHit)
511 { 514 {
512 Filter.prototype.serialize.call(this, buffer); 515 Filter.prototype.serialize.call(this, buffer);
513 if (this._disabled) 516 if (this._disabled)
514 buffer.push("disabled=true"); 517 buffer.push("disabled=true");
515 if (this._hitCount) 518 if (this._hitCount)
516 buffer.push("hitCount=" + this._hitCount); 519 buffer.push("hitCount=" + this._hitCount);
517 if (this._lastHit) 520 if (this._lastHit)
518 buffer.push("lastHit=" + this._lastHit); 521 buffer.push("lastHit=" + this._lastHit);
519 } 522 }
520 } 523 }
521 }); 524 });
522 525
523 /** 526 /**
524 * Abstract base class for RegExp-based filters 527 * Abstract base class for RegExp-based filters
525 * @param {string} text see Filter() 528 * @param {string} text see Filter()
526 * @param {string} regexpSource filter part that the regular expression should 529 * @param {string} regexpSource
527 * be build from 530 * filter part that the regular expression should be build from
528 * @param {number} [contentType] Content types the filter applies to, 531 * @param {number} [contentType]
529 * combination of values from RegExpFilter.typeMap 532 * Content types the filter applies to, combination of values from
530 * @param {boolean} [matchCase] Defines whether the filter should distinguish 533 * RegExpFilter.typeMap
531 * between lower and upper case letters 534 * @param {boolean} [matchCase]
532 * @param {string} [domains] Domains that the filter is restricted to, 535 * Defines whether the filter should distinguish between lower and upper case
533 * e.g. "foo.com|bar.com|~baz.com" 536 * letters
534 * @param {boolean} [thirdParty] Defines whether the filter should apply to 537 * @param {string} [domains]
535 * third-party or first-party content only 538 * Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com"
536 * @param {string} [sitekeys] Public keys of websites that this filter should 539 * @param {boolean} [thirdParty]
537 * apply to 540 * Defines whether the filter should apply to third-party or first-party
541 * content only
542 * @param {string} [sitekeys]
543 * Public keys of websites that this filter should apply to
538 * @constructor 544 * @constructor
539 * @augments ActiveFilter 545 * @augments ActiveFilter
540 */ 546 */
541 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, 547 function RegExpFilter(text, regexpSource, contentType, matchCase, domains,
542 thirdParty, sitekeys) 548 thirdParty, sitekeys)
543 { 549 {
544 ActiveFilter.call(this, text, domains, sitekeys); 550 ActiveFilter.call(this, text, domains, sitekeys);
545 551
546 if (contentType != null) 552 if (contentType != null)
547 this.contentType = contentType; 553 this.contentType = contentType;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 * @param {boolean} thirdParty should be true if the URL is a third-party 676 * @param {boolean} thirdParty should be true if the URL is a third-party
671 * request 677 * request
672 * @param {string} sitekey public key provided by the document 678 * @param {string} sitekey public key provided by the document
673 * @return {boolean} true in case of a match 679 * @return {boolean} true in case of a match
674 */ 680 */
675 matches(location, typeMask, docDomain, thirdParty, sitekey) 681 matches(location, typeMask, docDomain, thirdParty, sitekey)
676 { 682 {
677 if (this.contentType & typeMask && 683 if (this.contentType & typeMask &&
678 (this.thirdParty == null || this.thirdParty == thirdParty) && 684 (this.thirdParty == null || this.thirdParty == thirdParty) &&
679 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) 685 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location))
686 {
680 return true; 687 return true;
688 }
681 return false; 689 return false;
682 } 690 }
683 }); 691 });
684 692
685 // Required to optimize Matcher, see also RegExpFilter.prototype.length 693 // Required to optimize Matcher, see also RegExpFilter.prototype.length
686 Object.defineProperty(RegExpFilter.prototype, "0", { 694 Object.defineProperty(RegExpFilter.prototype, "0", {
687 get() { return this; } 695 get() { return this; }
688 }); 696 });
689 697
690 /** 698 /**
691 * Creates a RegExp filter from its text representation 699 * Creates a RegExp filter from its text representation
692 * @param {string} text same as in Filter() 700 * @param {string} text same as in Filter()
693 * @return {RegExpFilter} 701 * @return {Filter}
694 */ 702 */
695 RegExpFilter.fromText = function(text) 703 RegExpFilter.fromText = function(text)
696 { 704 {
697 let blocking = true; 705 let blocking = true;
698 let origText = text; 706 let origText = text;
699 if (text.indexOf("@@") == 0) 707 if (text.indexOf("@@") == 0)
700 { 708 {
701 blocking = false; 709 blocking = false;
702 text = text.substr(2); 710 text = text.substr(2);
703 } 711 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 819
812 /** 820 /**
813 * Class for blocking filters 821 * Class for blocking filters
814 * @param {string} text see Filter() 822 * @param {string} text see Filter()
815 * @param {string} regexpSource see RegExpFilter() 823 * @param {string} regexpSource see RegExpFilter()
816 * @param {number} contentType see RegExpFilter() 824 * @param {number} contentType see RegExpFilter()
817 * @param {boolean} matchCase see RegExpFilter() 825 * @param {boolean} matchCase see RegExpFilter()
818 * @param {string} domains see RegExpFilter() 826 * @param {string} domains see RegExpFilter()
819 * @param {boolean} thirdParty see RegExpFilter() 827 * @param {boolean} thirdParty see RegExpFilter()
820 * @param {string} sitekeys see RegExpFilter() 828 * @param {string} sitekeys see RegExpFilter()
821 * @param {boolean} collapse defines whether the filter should collapse blocked 829 * @param {boolean} collapse
822 * content, can be null 830 * defines whether the filter should collapse blocked content, can be null
823 * @constructor 831 * @constructor
824 * @augments RegExpFilter 832 * @augments RegExpFilter
825 */ 833 */
826 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, 834 function BlockingFilter(text, regexpSource, contentType, matchCase, domains,
827 thirdParty, sitekeys, collapse) 835 thirdParty, sitekeys, collapse)
828 { 836 {
829 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, 837 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains,
830 thirdParty, sitekeys); 838 thirdParty, sitekeys);
831 839
832 this.collapse = collapse; 840 this.collapse = collapse;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 * CSS selector for the HTML elements that should be hidden 922 * CSS selector for the HTML elements that should be hidden
915 * @type {string} 923 * @type {string}
916 */ 924 */
917 selector: null 925 selector: null
918 }); 926 });
919 927
920 /** 928 /**
921 * Creates an element hiding filter from a pre-parsed text representation 929 * Creates an element hiding filter from a pre-parsed text representation
922 * 930 *
923 * @param {string} text same as in Filter() 931 * @param {string} text same as in Filter()
924 * @param {string} domain domain part of the text representation 932 * @param {string} domain
925 * (can be empty) 933 * domain part of the text representation (can be empty)
926 * @param {boolean} isException exception rule indicator 934 * @param {boolean} isException exception rule indicator
927 * @param {string} tagName tag name part (can be empty) 935 * @param {string} tagName tag name part (can be empty)
928 * @param {string} attrRules attribute matching rules (can be empty) 936 * @param {string} attrRules attribute matching rules (can be empty)
929 * @param {string} selector raw CSS selector (can be empty) 937 * @param {string} selector raw CSS selector (can be empty)
930 * @return {ElemHideFilter|ElemHideException| 938 * @return {ElemHideFilter|ElemHideException|
931 * ElemHideEmulationFilter|InvalidFilter} 939 * ElemHideEmulationFilter|InvalidFilter}
932 */ 940 */
933 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, 941 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules,
934 selector) 942 selector)
935 { 943 {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 */ 1046 */
1039 function ElemHideEmulationFilter(text, domains, selector) 1047 function ElemHideEmulationFilter(text, domains, selector)
1040 { 1048 {
1041 ElemHideBase.call(this, text, domains, selector); 1049 ElemHideBase.call(this, text, domains, selector);
1042 } 1050 }
1043 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; 1051 exports.ElemHideEmulationFilter = ElemHideEmulationFilter;
1044 1052
1045 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { 1053 ElemHideEmulationFilter.prototype = extend(ElemHideBase, {
1046 type: "elemhideemulation" 1054 type: "elemhideemulation"
1047 }); 1055 });
LEFTRIGHT

Powered by Google App Engine
This is Rietveld