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

Side by Side Diff: lib/filterClasses.js

Issue 29550662: Issue 5735 - Use JS Map instead of Object for property domains of Filter objects (Closed) Base URL: https://github.com/adblockplus/adblockpluscore.git
Patch Set: Created Sept. 20, 2017, 12:59 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 /** 352 /**
353 * Determines whether domainSource is already upper-case, 353 * Determines whether domainSource is already upper-case,
354 * can be overridden by subclasses. 354 * can be overridden by subclasses.
355 * @type {boolean} 355 * @type {boolean}
356 */ 356 */
357 domainSourceIsUpperCase: false, 357 domainSourceIsUpperCase: false,
358 358
359 /** 359 /**
360 * Map containing domains that this filter should match on/not match 360 * Map containing domains that this filter should match on/not match
361 * on or null if the filter should match on all domains 361 * on or null if the filter should match on all domains
362 * @type {Object} 362 * @type {?Map.<string,boolean>}
363 */ 363 */
364 get domains() 364 get domains()
365 { 365 {
366 // Despite this property being cached, the getter is called 366 // Despite this property being cached, the getter is called
367 // several times on Safari, due to WebKit bug 132872 367 // several times on Safari, due to WebKit bug 132872
368 let prop = Object.getOwnPropertyDescriptor(this, "domains"); 368 let prop = Object.getOwnPropertyDescriptor(this, "domains");
369 if (prop) 369 if (prop)
370 return prop.value; 370 return prop.value;
371 371
372 let domains = null; 372 let domains = null;
373 373
374 if (this.domainSource) 374 if (this.domainSource)
375 { 375 {
376 let source = this.domainSource; 376 let source = this.domainSource;
377 if (!this.domainSourceIsUpperCase) 377 if (!this.domainSourceIsUpperCase)
378 { 378 {
379 // RegExpFilter already have uppercase domains 379 // RegExpFilter already have uppercase domains
380 source = source.toUpperCase(); 380 source = source.toUpperCase();
381 } 381 }
382 let list = source.split(this.domainSeparator); 382 let list = source.split(this.domainSeparator);
383 if (list.length == 1 && list[0][0] != "~") 383 if (list.length == 1 && list[0][0] != "~")
384 { 384 {
385 // Fast track for the common one-domain scenario 385 // Fast track for the common one-domain scenario
386 domains = Object.create(null); 386 domains = new Map();
387 domains[""] = false; 387 domains.set("", false);
388 if (this.ignoreTrailingDot) 388 if (this.ignoreTrailingDot)
389 list[0] = list[0].replace(/\.+$/, ""); 389 list[0] = list[0].replace(/\.+$/, "");
390 domains[list[0]] = true; 390 domains.set(list[0], true);
Wladimir Palant 2017/09/21 08:11:44 You can initialize the Map object immediately: new
sergei 2017/09/21 10:50:34 Done. BTW, I would like to pay attention to the im
Wladimir Palant 2017/09/21 10:53:01 Feel free to measure that. I assume that the JS en
391 } 391 }
392 else 392 else
393 { 393 {
394 let hasIncludes = false; 394 let hasIncludes = false;
395 for (let i = 0; i < list.length; i++) 395 for (let i = 0; i < list.length; i++)
396 { 396 {
397 let domain = list[i]; 397 let domain = list[i];
398 if (this.ignoreTrailingDot) 398 if (this.ignoreTrailingDot)
399 domain = domain.replace(/\.+$/, ""); 399 domain = domain.replace(/\.+$/, "");
400 if (domain == "") 400 if (domain == "")
401 continue; 401 continue;
402 402
403 let include; 403 let include;
404 if (domain[0] == "~") 404 if (domain[0] == "~")
405 { 405 {
406 include = false; 406 include = false;
407 domain = domain.substr(1); 407 domain = domain.substr(1);
408 } 408 }
409 else 409 else
410 { 410 {
411 include = true; 411 include = true;
412 hasIncludes = true; 412 hasIncludes = true;
413 } 413 }
414 414
415 if (!domains) 415 if (!domains)
416 domains = Object.create(null); 416 domains = new Map();
417 417
418 domains[domain] = include; 418 domains.set(domain, include);
419 } 419 }
420 if (domains) 420 if (domains)
421 domains[""] = !hasIncludes; 421 domains.set("", !hasIncludes);
422 } 422 }
423 423
424 this.domainSource = null; 424 this.domainSource = null;
425 } 425 }
426 426
427 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); 427 Object.defineProperty(this, "domains", {value: domains, enumerable: true});
428 return this.domains; 428 return this.domains;
429 }, 429 },
430 430
431 /** 431 /**
(...skipping 19 matching lines...) Expand all
451 return false; 451 return false;
452 } 452 }
453 453
454 // If no domains are set the rule matches everywhere 454 // If no domains are set the rule matches everywhere
455 if (!this.domains) 455 if (!this.domains)
456 return true; 456 return true;
457 457
458 // If the document has no host name, match only if the filter 458 // If the document has no host name, match only if the filter
459 // isn't restricted to specific domains 459 // isn't restricted to specific domains
460 if (!docDomain) 460 if (!docDomain)
461 return this.domains[""]; 461 return this.domains.get("");
462 462
463 if (this.ignoreTrailingDot) 463 if (this.ignoreTrailingDot)
464 docDomain = docDomain.replace(/\.+$/, ""); 464 docDomain = docDomain.replace(/\.+$/, "");
465 docDomain = docDomain.toUpperCase(); 465 docDomain = docDomain.toUpperCase();
466 466
467 while (true) 467 while (true)
468 { 468 {
469 if (docDomain in this.domains) 469 let isDomainIncluded = this.domains.get(docDomain);
470 return this.domains[docDomain]; 470 if (isDomainIncluded != undefined)
Wladimir Palant 2017/09/21 08:11:44 We usually use the typeof operator: `typeof isDoma
sergei 2017/09/21 10:50:34 Acknowledged.
471 return isDomainIncluded;
471 472
472 let nextDot = docDomain.indexOf("."); 473 let nextDot = docDomain.indexOf(".");
473 if (nextDot < 0) 474 if (nextDot < 0)
474 break; 475 break;
475 docDomain = docDomain.substr(nextDot + 1); 476 docDomain = docDomain.substr(nextDot + 1);
476 } 477 }
477 return this.domains[""]; 478 return this.domains.get("");
478 }, 479 },
479 480
480 /** 481 /**
481 * Checks whether this filter is active only on a domain and its subdomains. 482 * Checks whether this filter is active only on a domain and its subdomains.
482 * @param {string} docDomain 483 * @param {string} docDomain
483 * @return {boolean} 484 * @return {boolean}
484 */ 485 */
485 isActiveOnlyOnDomain(docDomain) 486 isActiveOnlyOnDomain(docDomain)
486 { 487 {
487 if (!docDomain || !this.domains || this.domains[""]) 488 if (!docDomain || !this.domains || this.domains.get(""))
488 return false; 489 return false;
489 490
490 if (this.ignoreTrailingDot) 491 if (this.ignoreTrailingDot)
491 docDomain = docDomain.replace(/\.+$/, ""); 492 docDomain = docDomain.replace(/\.+$/, "");
492 docDomain = docDomain.toUpperCase(); 493 docDomain = docDomain.toUpperCase();
493 494
494 for (let domain in this.domains) 495 for (let [domain, isIncluded] of this.domains)
495 { 496 {
496 if (this.domains[domain] && domain != docDomain) 497 if (isIncluded && domain != docDomain)
497 { 498 {
498 if (domain.length <= docDomain.length) 499 if (domain.length <= docDomain.length)
499 return false; 500 return false;
500 501
501 if (!domain.endsWith("." + docDomain)) 502 if (!domain.endsWith("." + docDomain))
502 return false; 503 return false;
503 } 504 }
504 } 505 }
505 506
506 return true; 507 return true;
507 }, 508 },
508 509
509 /** 510 /**
510 * Checks whether this filter is generic or specific 511 * Checks whether this filter is generic or specific
511 * @return {boolean} 512 * @return {boolean}
512 */ 513 */
513 isGeneric() 514 isGeneric()
514 { 515 {
515 return !(this.sitekeys && this.sitekeys.length) && 516 return !(this.sitekeys && this.sitekeys.length) &&
516 (!this.domains || this.domains[""]); 517 (!this.domains || this.domains.get(""));
517 }, 518 },
518 519
519 /** 520 /**
520 * See Filter.serialize() 521 * See Filter.serialize()
521 * @inheritdoc 522 * @inheritdoc
522 */ 523 */
523 serialize(buffer) 524 serialize(buffer)
524 { 525 {
525 if (this._disabled || this._hitCount || this._lastHit) 526 if (this._disabled || this._hitCount || this._lastHit)
526 { 527 {
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 */ 1021 */
1021 function ElemHideEmulationFilter(text, domains, selector) 1022 function ElemHideEmulationFilter(text, domains, selector)
1022 { 1023 {
1023 ElemHideBase.call(this, text, domains, selector); 1024 ElemHideBase.call(this, text, domains, selector);
1024 } 1025 }
1025 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; 1026 exports.ElemHideEmulationFilter = ElemHideEmulationFilter;
1026 1027
1027 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { 1028 ElemHideEmulationFilter.prototype = extend(ElemHideBase, {
1028 type: "elemhideemulation" 1029 type: "elemhideemulation"
1029 }); 1030 });
OLDNEW
« lib/elemHide.js ('K') | « lib/elemHide.js ('k') | test/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld