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

Side by Side Diff: lib/filterClasses.js

Issue 4559243822759936: Issue 431/432 - Remove special handling for the $sitekey option (Closed)
Patch Set: Rebased and added comment Created Sept. 1, 2014, 9:48 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 | « lib/contentPolicy.js ('k') | lib/matcher.js » ('j') | 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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 208
209 /** 209 /**
210 * See Filter.serialize() 210 * See Filter.serialize()
211 */ 211 */
212 serialize: function(buffer) {} 212 serialize: function(buffer) {}
213 }; 213 };
214 214
215 /** 215 /**
216 * Abstract base class for filters that can get hits 216 * Abstract base class for filters that can get hits
217 * @param {String} text see Filter() 217 * @param {String} text see Filter()
218 * @param {String} domains (optional) Domains that the filter is restricted to separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" 218 * @param {String} [domains] Domains that the filter is restricted to separated by domainSeparator e.g. "foo.com|bar.com|~baz.com"
219 * @constructor 219 * @constructor
220 * @augments Filter 220 * @augments Filter
221 */ 221 */
222 function ActiveFilter(text, domains) 222 function ActiveFilter(text, domains)
223 { 223 {
224 Filter.call(this, text); 224 Filter.call(this, text);
225 225
226 this.domainSource = domains; 226 this.domainSource = domains;
227 } 227 }
228 exports.ActiveFilter = ActiveFilter; 228 exports.ActiveFilter = ActiveFilter;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 } 380 }
381 381
382 this.domainSource = null; 382 this.domainSource = null;
383 } 383 }
384 384
385 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); 385 Object.defineProperty(this, "domains", {value: domains, enumerable: true});
386 return this.domains; 386 return this.domains;
387 }, 387 },
388 388
389 /** 389 /**
390 * Array containing public keys of websites that this filter should apply to
391 * @type Array of String
392 */
393 sitekeys: null,
394
395 /**
390 * Checks whether this filter is active on a domain. 396 * Checks whether this filter is active on a domain.
397 * @param {String} docDomain domain name of the document that loads the URL
398 * @param {String} [sitekey] public key provided by the document
399 * @return {Boolean} true in case of the filter being active
391 */ 400 */
392 isActiveOnDomain: function(/**String*/ docDomain) /**Boolean*/ 401 isActiveOnDomain: function(docDomain, sitekey)
393 { 402 {
403 // Sitekeys are case-sensitive so we shouldn't convert them to upper-case to avoid false
404 // positives here. Instead we need to change the way filter options are pars ed.
405 if (this.sitekeys && (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase( )) < 0))
406 return false;
407
394 // If no domains are set the rule matches everywhere 408 // If no domains are set the rule matches everywhere
395 if (!this.domains) 409 if (!this.domains)
396 return true; 410 return true;
397 411
398 // If the document has no host name, match only if the filter isn't restrict ed to specific domains 412 // If the document has no host name, match only if the filter isn't restrict ed to specific domains
399 if (!docDomain) 413 if (!docDomain)
400 return this.domains[""]; 414 return this.domains[""];
401 415
402 if (this.ignoreTrailingDot) 416 if (this.ignoreTrailingDot)
403 docDomain = docDomain.replace(/\.+$/, ""); 417 docDomain = docDomain.replace(/\.+$/, "");
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 if (this._lastHit) 464 if (this._lastHit)
451 buffer.push("lastHit=" + this._lastHit); 465 buffer.push("lastHit=" + this._lastHit);
452 } 466 }
453 } 467 }
454 }; 468 };
455 469
456 /** 470 /**
457 * Abstract base class for RegExp-based filters 471 * Abstract base class for RegExp-based filters
458 * @param {String} text see Filter() 472 * @param {String} text see Filter()
459 * @param {String} regexpSource filter part that the regular expression should b e build from 473 * @param {String} regexpSource filter part that the regular expression should b e build from
460 * @param {Number} contentType (optional) Content types the filter applies to, combination of values from RegExpFilter.typeMap 474 * @param {Number} [contentType] Content types the filter applies to, combinatio n of values from RegExpFilter.typeMap
461 * @param {Boolean} matchCase (optional) Defines whether the filter should dis tinguish between lower and upper case letters 475 * @param {Boolean} [matchCase] Defines whether the filter should distinguish be tween lower and upper case letters
462 * @param {String} domains (optional) Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" 476 * @param {String} [domains] Domains that the filter is restricted to, e.g. "foo .com|bar.com|~baz.com"
463 * @param {Boolean} thirdParty (optional) Defines whether the filter should app ly to third-party or first-party content only 477 * @param {Boolean} [thirdParty] Defines whether the filter should apply to thir d-party or first-party content only
478 * @param {String} [sitekeys] Public keys of websites that this filter should ap ply to
464 * @constructor 479 * @constructor
465 * @augments ActiveFilter 480 * @augments ActiveFilter
466 */ 481 */
467 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third Party) 482 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third Party, sitekeys)
468 { 483 {
469 ActiveFilter.call(this, text, domains); 484 ActiveFilter.call(this, text, domains, sitekeys);
470 485
471 if (contentType != null) 486 if (contentType != null)
472 this.contentType = contentType; 487 this.contentType = contentType;
473 if (matchCase) 488 if (matchCase)
474 this.matchCase = matchCase; 489 this.matchCase = matchCase;
475 if (thirdParty != null) 490 if (thirdParty != null)
476 this.thirdParty = thirdParty; 491 this.thirdParty = thirdParty;
492 if (sitekeys != null)
493 this.sitekeySource = sitekeys;
477 494
478 if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpS ource.length - 1] == "/") 495 if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpS ource.length - 1] == "/")
479 { 496 {
480 // The filter is a regular expression - convert it immediately to catch synt ax errors 497 // The filter is a regular expression - convert it immediately to catch synt ax errors
481 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), thi s.matchCase ? "" : "i"); 498 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), thi s.matchCase ? "" : "i");
482 Object.defineProperty(this, "regexp", {value: regexp}); 499 Object.defineProperty(this, "regexp", {value: regexp});
483 } 500 }
484 else 501 else
485 { 502 {
486 // No need to convert this filter to regular expression yet, do it on demand 503 // No need to convert this filter to regular expression yet, do it on demand
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 * @type Boolean 571 * @type Boolean
555 */ 572 */
556 matchCase: false, 573 matchCase: false,
557 /** 574 /**
558 * Defines whether the filter should apply to third-party or first-party conte nt only. Can be null (apply to all content). 575 * Defines whether the filter should apply to third-party or first-party conte nt only. Can be null (apply to all content).
559 * @type Boolean 576 * @type Boolean
560 */ 577 */
561 thirdParty: null, 578 thirdParty: null,
562 579
563 /** 580 /**
581 * String that the sitekey property should be generated from
582 * @type String
583 */
584 sitekeySource: null,
585
586 /**
587 * Array containing public keys of websites that this filter should apply to
588 * @type Array of String
589 */
590 get sitekeys()
591 {
592 let sitekeys = null;
593
594 if (this.sitekeySource)
595 {
596 sitekeys = this.sitekeySource.split("|");
597 this.sitekeySource = null;
598 }
599
600 Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true}) ;
601 return this.sitekeys;
602 },
603
604 /**
564 * Tests whether the URL matches this filter 605 * Tests whether the URL matches this filter
565 * @param {String} location URL to be tested 606 * @param {String} location URL to be tested
566 * @param {String} contentType content type identifier of the URL 607 * @param {String} contentType content type identifier of the URL
567 * @param {String} docDomain domain name of the document that loads the URL 608 * @param {String} docDomain domain name of the document that loads the URL
568 * @param {Boolean} thirdParty should be true if the URL is a third-party requ est 609 * @param {Boolean} thirdParty should be true if the URL is a third-party requ est
610 * @param {String} sitekey public key provided by the document
569 * @return {Boolean} true in case of a match 611 * @return {Boolean} true in case of a match
570 */ 612 */
571 matches: function(location, contentType, docDomain, thirdParty) 613 matches: function(location, contentType, docDomain, thirdParty, sitekey)
572 { 614 {
573 if (this.regexp.test(location) && 615 if (this.regexp.test(location) &&
574 (RegExpFilter.typeMap[contentType] & this.contentType) != 0 && 616 (RegExpFilter.typeMap[contentType] & this.contentType) != 0 &&
575 (this.thirdParty == null || this.thirdParty == thirdParty) && 617 (this.thirdParty == null || this.thirdParty == thirdParty) &&
576 this.isActiveOnDomain(docDomain)) 618 this.isActiveOnDomain(docDomain, sitekey))
577 { 619 {
578 return true; 620 return true;
579 } 621 }
580 622
581 return false; 623 return false;
582 } 624 }
583 }; 625 };
584 626
585 // Required to optimize Matcher, see also RegExpFilter.prototype.length 627 // Required to optimize Matcher, see also RegExpFilter.prototype.length
586 Object.defineProperty(RegExpFilter.prototype, "0", 628 Object.defineProperty(RegExpFilter.prototype, "0",
(...skipping 11 matching lines...) Expand all
598 let origText = text; 640 let origText = text;
599 if (text.indexOf("@@") == 0) 641 if (text.indexOf("@@") == 0)
600 { 642 {
601 blocking = false; 643 blocking = false;
602 text = text.substr(2); 644 text = text.substr(2);
603 } 645 }
604 646
605 let contentType = null; 647 let contentType = null;
606 let matchCase = null; 648 let matchCase = null;
607 let domains = null; 649 let domains = null;
608 let siteKeys = null; 650 let sitekeys = null;
609 let thirdParty = null; 651 let thirdParty = null;
610 let collapse = null; 652 let collapse = null;
611 let options; 653 let options;
612 let match = (text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null); 654 let match = (text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null);
613 if (match) 655 if (match)
614 { 656 {
615 options = match[1].toUpperCase().split(","); 657 options = match[1].toUpperCase().split(",");
616 text = match.input.substr(0, match.index); 658 text = match.input.substr(0, match.index);
617 for (let option of options) 659 for (let option of options)
618 { 660 {
(...skipping 25 matching lines...) Expand all
644 domains = value; 686 domains = value;
645 else if (option == "THIRD_PARTY") 687 else if (option == "THIRD_PARTY")
646 thirdParty = true; 688 thirdParty = true;
647 else if (option == "~THIRD_PARTY") 689 else if (option == "~THIRD_PARTY")
648 thirdParty = false; 690 thirdParty = false;
649 else if (option == "COLLAPSE") 691 else if (option == "COLLAPSE")
650 collapse = true; 692 collapse = true;
651 else if (option == "~COLLAPSE") 693 else if (option == "~COLLAPSE")
652 collapse = false; 694 collapse = false;
653 else if (option == "SITEKEY" && typeof value != "undefined") 695 else if (option == "SITEKEY" && typeof value != "undefined")
654 siteKeys = value.split(/\|/); 696 sitekeys = value;
655 else 697 else
656 return new InvalidFilter(origText, "Unknown option " + option.toLowerCas e()); 698 return new InvalidFilter(origText, "Unknown option " + option.toLowerCas e());
657 } 699 }
658 } 700 }
659 701
660 if (!blocking && (contentType == null || (contentType & RegExpFilter.typeMap.D OCUMENT)) && 702 if (!blocking && (contentType == null || (contentType & RegExpFilter.typeMap.D OCUMENT)) &&
661 (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text )) 703 (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text ))
662 { 704 {
663 // Exception filters shouldn't apply to pages by default unless they start w ith a protocol name 705 // Exception filters shouldn't apply to pages by default unless they start w ith a protocol name
664 if (contentType == null) 706 if (contentType == null)
665 contentType = RegExpFilter.prototype.contentType; 707 contentType = RegExpFilter.prototype.contentType;
666 contentType &= ~RegExpFilter.typeMap.DOCUMENT; 708 contentType &= ~RegExpFilter.typeMap.DOCUMENT;
667 } 709 }
668 if (!blocking && siteKeys)
669 contentType = RegExpFilter.typeMap.DOCUMENT;
670 710
671 try 711 try
672 { 712 {
673 if (blocking) 713 if (blocking)
674 return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, collapse); 714 return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse);
675 else 715 else
676 return new WhitelistFilter(origText, text, contentType, matchCase, domains , thirdParty, siteKeys); 716 return new WhitelistFilter(origText, text, contentType, matchCase, domains , thirdParty, sitekeys);
677 } 717 }
678 catch (e) 718 catch (e)
679 { 719 {
680 return new InvalidFilter(origText, e); 720 return new InvalidFilter(origText, e);
681 } 721 }
682 } 722 }
683 723
684 /** 724 /**
685 * Maps type strings like "SCRIPT" or "OBJECT" to bit masks 725 * Maps type strings like "SCRIPT" or "OBJECT" to bit masks
686 */ 726 */
(...skipping 23 matching lines...) Expand all
710 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFi lter.typeMap.POPUP); 750 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFi lter.typeMap.POPUP);
711 751
712 /** 752 /**
713 * Class for blocking filters 753 * Class for blocking filters
714 * @param {String} text see Filter() 754 * @param {String} text see Filter()
715 * @param {String} regexpSource see RegExpFilter() 755 * @param {String} regexpSource see RegExpFilter()
716 * @param {Number} contentType see RegExpFilter() 756 * @param {Number} contentType see RegExpFilter()
717 * @param {Boolean} matchCase see RegExpFilter() 757 * @param {Boolean} matchCase see RegExpFilter()
718 * @param {String} domains see RegExpFilter() 758 * @param {String} domains see RegExpFilter()
719 * @param {Boolean} thirdParty see RegExpFilter() 759 * @param {Boolean} thirdParty see RegExpFilter()
760 * @param {String} sitekeys see RegExpFilter()
720 * @param {Boolean} collapse defines whether the filter should collapse blocked content, can be null 761 * @param {Boolean} collapse defines whether the filter should collapse blocked content, can be null
721 * @constructor 762 * @constructor
722 * @augments RegExpFilter 763 * @augments RegExpFilter
723 */ 764 */
724 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thi rdParty, collapse) 765 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thi rdParty, sitekeys, collapse)
725 { 766 {
726 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t hirdParty); 767 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t hirdParty, sitekeys);
727 768
728 this.collapse = collapse; 769 this.collapse = collapse;
729 } 770 }
730 exports.BlockingFilter = BlockingFilter; 771 exports.BlockingFilter = BlockingFilter;
731 772
732 BlockingFilter.prototype = 773 BlockingFilter.prototype =
733 { 774 {
734 __proto__: RegExpFilter.prototype, 775 __proto__: RegExpFilter.prototype,
735 776
736 /** 777 /**
737 * Defines whether the filter should collapse blocked content. Can be null (us e the global preference). 778 * Defines whether the filter should collapse blocked content. Can be null (us e the global preference).
738 * @type Boolean 779 * @type Boolean
739 */ 780 */
740 collapse: null 781 collapse: null
741 }; 782 };
742 783
743 /** 784 /**
744 * Class for whitelist filters 785 * Class for whitelist filters
745 * @param {String} text see Filter() 786 * @param {String} text see Filter()
746 * @param {String} regexpSource see RegExpFilter() 787 * @param {String} regexpSource see RegExpFilter()
747 * @param {Number} contentType see RegExpFilter() 788 * @param {Number} contentType see RegExpFilter()
748 * @param {Boolean} matchCase see RegExpFilter() 789 * @param {Boolean} matchCase see RegExpFilter()
749 * @param {String} domains see RegExpFilter() 790 * @param {String} domains see RegExpFilter()
750 * @param {Boolean} thirdParty see RegExpFilter() 791 * @param {Boolean} thirdParty see RegExpFilter()
751 * @param {String[]} siteKeys public keys of websites that this filter should ap ply to 792 * @param {String} sitekeys see RegExpFilter()
752 * @constructor 793 * @constructor
753 * @augments RegExpFilter 794 * @augments RegExpFilter
754 */ 795 */
755 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, th irdParty, siteKeys) 796 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, th irdParty, sitekeys)
756 { 797 {
757 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t hirdParty); 798 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t hirdParty, sitekeys);
758
759 if (siteKeys != null)
760 this.siteKeys = siteKeys;
761 } 799 }
762 exports.WhitelistFilter = WhitelistFilter; 800 exports.WhitelistFilter = WhitelistFilter;
763 801
764 WhitelistFilter.prototype = 802 WhitelistFilter.prototype =
765 { 803 {
766 __proto__: RegExpFilter.prototype, 804 __proto__: RegExpFilter.prototype
767
768 /**
769 * List of public keys of websites that this filter should apply to
770 * @type String[]
771 */
772 siteKeys: null
773 } 805 }
774 806
775 /** 807 /**
776 * Base class for element hiding filters 808 * Base class for element hiding filters
777 * @param {String} text see Filter() 809 * @param {String} text see Filter()
778 * @param {String} domains (optional) Host names or domains the filter should be restricted to 810 * @param {String} [domains] Host names or domains the filter should be restrict ed to
779 * @param {String} selector CSS selector for the HTML elements that should be hidden 811 * @param {String} selector CSS selector for the HTML elements that should be hidden
780 * @constructor 812 * @constructor
781 * @augments ActiveFilter 813 * @augments ActiveFilter
782 */ 814 */
783 function ElemHideBase(text, domains, selector) 815 function ElemHideBase(text, domains, selector)
784 { 816 {
785 ActiveFilter.call(this, text, domains || null); 817 ActiveFilter.call(this, text, domains || null);
786 818
787 if (domains) 819 if (domains)
788 this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, " ").toLowerCase(); 820 this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, " ").toLowerCase();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 function ElemHideException(text, domains, selector) 934 function ElemHideException(text, domains, selector)
903 { 935 {
904 ElemHideBase.call(this, text, domains, selector); 936 ElemHideBase.call(this, text, domains, selector);
905 } 937 }
906 exports.ElemHideException = ElemHideException; 938 exports.ElemHideException = ElemHideException;
907 939
908 ElemHideException.prototype = 940 ElemHideException.prototype =
909 { 941 {
910 __proto__: ElemHideBase.prototype 942 __proto__: ElemHideBase.prototype
911 }; 943 };
OLDNEW
« no previous file with comments | « lib/contentPolicy.js ('k') | lib/matcher.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld