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

Delta Between Two Patch Sets: lib/filterClasses.js

Issue 4559243822759936: Issue 431/432 - Remove special handling for the $sitekey option (Closed)
Left Patch Set: Created Aug. 11, 2014, 5:13 p.m.
Right Patch Set: Made changes for WebKit bug 132872 Created Sept. 1, 2014, 3:27 p.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/contentPolicy.js ('k') | lib/matcher.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 <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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 * @type Boolean 317 * @type Boolean
318 */ 318 */
319 domainSourceIsUpperCase: false, 319 domainSourceIsUpperCase: false,
320 320
321 /** 321 /**
322 * Map containing domains that this filter should match on/not match on or nul l if the filter should match on all domains 322 * Map containing domains that this filter should match on/not match on or nul l if the filter should match on all domains
323 * @type Object 323 * @type Object
324 */ 324 */
325 get domains() 325 get domains()
326 { 326 {
327 // Despite this property being cached, the getter is called
328 // several times on Safari, due to WebKit bug 132872
329 let prop = Object.getOwnPropertyDescriptor(this, "domains");
330 if (prop)
331 return prop.value;
332
327 let domains = null; 333 let domains = null;
328 334
329 if (this.domainSource) 335 if (this.domainSource)
330 { 336 {
331 let source = this.domainSource; 337 let source = this.domainSource;
332 if (!this.domainSourceIsUpperCase) { 338 if (!this.domainSourceIsUpperCase) {
333 // RegExpFilter already have uppercase domains 339 // RegExpFilter already have uppercase domains
334 source = source.toUpperCase(); 340 source = source.toUpperCase();
335 } 341 }
336 let list = source.split(this.domainSeparator); 342 let list = source.split(this.domainSeparator);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 } 380 }
375 381
376 this.domainSource = null; 382 this.domainSource = null;
377 } 383 }
378 384
379 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); 385 Object.defineProperty(this, "domains", {value: domains, enumerable: true});
380 return this.domains; 386 return this.domains;
381 }, 387 },
382 388
383 /** 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 /**
384 * Checks whether this filter is active on a domain. 396 * Checks whether this filter is active on a domain.
385 * @param {String} docDomain domain name of the document that loads the URL 397 * @param {String} docDomain domain name of the document that loads the URL
386 * @param {String} sitekey (optional) public key provided by the document 398 * @param {String} [sitekey] public key provided by the document
387 * @return {Boolean} true in case of the filter being active 399 * @return {Boolean} true in case of the filter being active
388 */ 400 */
389 isActiveOnDomain: function(docDomain, sitekey) 401 isActiveOnDomain: function(docDomain, sitekey)
390 { 402 {
391 // If no domains or sitekeys are set the rule matches everywhere 403 // Sitekeys are case-sensitive so we shouldn't convert them to upper-case to avoid false
392 if (!this.domains && !this.sitekeys) 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
408 // If no domains are set the rule matches everywhere
409 if (!this.domains)
393 return true; 410 return true;
394 411
395 let activeDomain = true; 412 // If the document has no host name, match only if the filter isn't restrict ed to specific domains
396 if (this.domains) 413 if (!docDomain)
414 return this.domains[""];
415
416 if (this.ignoreTrailingDot)
417 docDomain = docDomain.replace(/\.+$/, "");
418 docDomain = docDomain.toUpperCase();
419
420 while (true)
397 { 421 {
398 if (!docDomain) 422 if (docDomain in this.domains)
399 // If the document has no host name, match only if the filter isn't rest ricted to specific domains 423 return this.domains[docDomain];
400 activeDomain = this.domains[""]; 424
401 else 425 let nextDot = docDomain.indexOf(".");
402 { 426 if (nextDot < 0)
403 if (this.ignoreTrailingDot) 427 break;
404 docDomain = docDomain.replace(/\.+$/, ""); 428 docDomain = docDomain.substr(nextDot + 1);
405 docDomain = docDomain.toUpperCase(); 429 }
406 430 return this.domains[""];
407 let domain = "";
408 while (true)
409 {
410 if (docDomain in this.domains)
411 {
412 domain = docDomain;
413 break;
414 }
415
416 let nextDot = docDomain.indexOf(".");
417 if (nextDot < 0)
418 break;
419 docDomain = docDomain.substr(nextDot + 1);
420 }
421 activeDomain = this.domains[domain];
422 }
423 }
424
425 let activeSitekey = true;
426 if (this.sitekeys)
427 {
428 if (!sitekey)
429 // If the document has no sitekey, match only if the filter isn't restri cted by sitekeys
430 activeSitekey = this.sitekeys[""];
431 else
432 {
433 let [key, signature] = sitekey.split("_", 2);
434 let formattedKey = key.replace(/=/g, "").toUpperCase();
435 if (formattedKey in this.sitekeys)
436 activeSitekey = this.sitekeys[formattedKey];
437 else
438 activeSitekey = this.sitekeys[""];
439 }
440 }
441 return activeDomain && activeSitekey;
442 }, 431 },
443 432
444 /** 433 /**
445 * Checks whether this filter is active only on a domain and its subdomains. 434 * Checks whether this filter is active only on a domain and its subdomains.
446 */ 435 */
447 isActiveOnlyOnDomain: function(/**String*/ docDomain) /**Boolean*/ 436 isActiveOnlyOnDomain: function(/**String*/ docDomain) /**Boolean*/
448 { 437 {
449 if (!docDomain || !this.domains || this.domains[""]) 438 if (!docDomain || !this.domains || this.domains[""])
450 return false; 439 return false;
451 440
(...skipping 23 matching lines...) Expand all
475 if (this._lastHit) 464 if (this._lastHit)
476 buffer.push("lastHit=" + this._lastHit); 465 buffer.push("lastHit=" + this._lastHit);
477 } 466 }
478 } 467 }
479 }; 468 };
480 469
481 /** 470 /**
482 * Abstract base class for RegExp-based filters 471 * Abstract base class for RegExp-based filters
483 * @param {String} text see Filter() 472 * @param {String} text see Filter()
484 * @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
485 * @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
486 * @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
487 * @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"
488 * @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
489 * @param {String} sitekeys (optional) Public keys of websites that this fil ter should apply to, e.g. "foo|bar|~baz" 478 * @param {String} [sitekeys] Public keys of websites that this filter should ap ply to
490 * @constructor 479 * @constructor
491 * @augments ActiveFilter 480 * @augments ActiveFilter
492 */ 481 */
493 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third Party, sitekeys) 482 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third Party, sitekeys)
494 { 483 {
495 ActiveFilter.call(this, text, domains, sitekeys); 484 ActiveFilter.call(this, text, domains, sitekeys);
496 485
497 if (contentType != null) 486 if (contentType != null)
498 this.contentType = contentType; 487 this.contentType = contentType;
499 if (matchCase) 488 if (matchCase)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 * Expression from which a regular expression should be generated - for delaye d creation of the regexp property 530 * Expression from which a regular expression should be generated - for delaye d creation of the regexp property
542 * @type String 531 * @type String
543 */ 532 */
544 regexpSource: null, 533 regexpSource: null,
545 /** 534 /**
546 * Regular expression to be used when testing against this filter 535 * Regular expression to be used when testing against this filter
547 * @type RegExp 536 * @type RegExp
548 */ 537 */
549 get regexp() 538 get regexp()
550 { 539 {
540 // Despite this property being cached, the getter is called
541 // several times on Safari, due to WebKit bug 132872
542 let prop = Object.getOwnPropertyDescriptor(this, "regexp");
543 if (prop)
544 return prop.value;
545
551 // Remove multiple wildcards 546 // Remove multiple wildcards
552 let source = this.regexpSource 547 let source = this.regexpSource
553 .replace(/\*+/g, "*") // remove multiple wildcards 548 .replace(/\*+/g, "*") // remove multiple wildcards
554 .replace(/\^\|$/, "^") // remove anchors following separator placeho lder 549 .replace(/\^\|$/, "^") // remove anchors following separator placeho lder
555 .replace(/\W/g, "\\$&") // escape special symbols 550 .replace(/\W/g, "\\$&") // escape special symbols
556 .replace(/\\\*/g, ".*") // replace wildcards by .* 551 .replace(/\\\*/g, ".*") // replace wildcards by .*
557 // process separator placeholders (all ANSI characters but alphanumeric ch aracters and _%.-) 552 // process separator placeholders (all ANSI characters but alphanumeric ch aracters and _%.-)
558 .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\ x60\\x7B-\\x7F]|$)") 553 .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\ x60\\x7B-\\x7F]|$)")
559 .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?") // process extended anchor at expression start 554 .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?") // process extended anchor at expression start
560 .replace(/^\\\|/, "^") // process anchor at expression start 555 .replace(/^\\\|/, "^") // process anchor at expression start
(...skipping 21 matching lines...) Expand all
582 */ 577 */
583 thirdParty: null, 578 thirdParty: null,
584 579
585 /** 580 /**
586 * String that the sitekey property should be generated from 581 * String that the sitekey property should be generated from
587 * @type String 582 * @type String
588 */ 583 */
589 sitekeySource: null, 584 sitekeySource: null,
590 585
591 /** 586 /**
592 * Map containing public keys of websites that this filter should apply to 587 * Array containing public keys of websites that this filter should apply to
593 * @type Object 588 * @type Array of String
594 */ 589 */
595 get sitekeys() 590 get sitekeys()
596 { 591 {
592 // Despite this property being cached, the getter is called
593 // several times on Safari, due to WebKit bug 132872
594 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys");
595 if (prop)
596 return prop.value;
597
597 let sitekeys = null; 598 let sitekeys = null;
598 599
599 if (this.sitekeySource) 600 if (this.sitekeySource)
600 { 601 {
601 let source = this.sitekeySource; 602 sitekeys = this.sitekeySource.split("|");
602 let list = source.split("|");
603 if (list.length == 1 && list[0][0] != "~")
604 {
605 // Fast track for the common one-sitekey scenario
606 sitekeys = {__proto__: null, "": false};
607 sitekeys[list[0]] = true;
608 }
609 else
610 {
611 let hasIncludes = false;
612 for (let i = 0; i < list.length; i++)
613 {
614 let sitekey = list[i];
615 if (sitekey == "")
616 continue;
617
618 let include;
619 if (sitekey[0] == "~")
620 {
621 include = false;
622 sitekey = sitekey.substr(1);
623 }
624 else
625 {
626 include = true;
627 hasIncludes = true;
628 }
629
630 if (!sitekeys)
631 sitekeys = Object.create(null);
632
633 sitekeys[sitekey] = include;
634 }
635 sitekeys[""] = !hasIncludes;
636 }
637
638 this.sitekeySource = null; 603 this.sitekeySource = null;
639 } 604 }
640 605
641 Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true}) ; 606 Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true}) ;
642 return this.sitekeys; 607 return this.sitekeys;
643 }, 608 },
644 609
645 /** 610 /**
646 * Tests whether the URL matches this filter 611 * Tests whether the URL matches this filter
647 * @param {String} location URL to be tested 612 * @param {String} location URL to be tested
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 exports.WhitelistFilter = WhitelistFilter; 806 exports.WhitelistFilter = WhitelistFilter;
842 807
843 WhitelistFilter.prototype = 808 WhitelistFilter.prototype =
844 { 809 {
845 __proto__: RegExpFilter.prototype 810 __proto__: RegExpFilter.prototype
846 } 811 }
847 812
848 /** 813 /**
849 * Base class for element hiding filters 814 * Base class for element hiding filters
850 * @param {String} text see Filter() 815 * @param {String} text see Filter()
851 * @param {String} domains (optional) Host names or domains the filter should be restricted to 816 * @param {String} [domains] Host names or domains the filter should be restrict ed to
852 * @param {String} selector CSS selector for the HTML elements that should be hidden 817 * @param {String} selector CSS selector for the HTML elements that should be hidden
853 * @constructor 818 * @constructor
854 * @augments ActiveFilter 819 * @augments ActiveFilter
855 */ 820 */
856 function ElemHideBase(text, domains, selector) 821 function ElemHideBase(text, domains, selector)
857 { 822 {
858 ActiveFilter.call(this, text, domains || null); 823 ActiveFilter.call(this, text, domains || null);
859 824
860 if (domains) 825 if (domains)
861 this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, " ").toLowerCase(); 826 this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, " ").toLowerCase();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 function ElemHideException(text, domains, selector) 940 function ElemHideException(text, domains, selector)
976 { 941 {
977 ElemHideBase.call(this, text, domains, selector); 942 ElemHideBase.call(this, text, domains, selector);
978 } 943 }
979 exports.ElemHideException = ElemHideException; 944 exports.ElemHideException = ElemHideException;
980 945
981 ElemHideException.prototype = 946 ElemHideException.prototype =
982 { 947 {
983 __proto__: ElemHideBase.prototype 948 __proto__: ElemHideBase.prototype
984 }; 949 };
LEFTRIGHT

Powered by Google App Engine
This is Rietveld