OLD | NEW |
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 Loading... |
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); | |
387 domains[""] = false; | |
388 if (this.ignoreTrailingDot) | 386 if (this.ignoreTrailingDot) |
389 list[0] = list[0].replace(/\.+$/, ""); | 387 list[0] = list[0].replace(/\.+$/, ""); |
390 domains[list[0]] = true; | 388 domains = new Map([["", false], [list[0], true]]); |
391 } | 389 } |
392 else | 390 else |
393 { | 391 { |
394 let hasIncludes = false; | 392 let hasIncludes = false; |
395 for (let i = 0; i < list.length; i++) | 393 for (let i = 0; i < list.length; i++) |
396 { | 394 { |
397 let domain = list[i]; | 395 let domain = list[i]; |
398 if (this.ignoreTrailingDot) | 396 if (this.ignoreTrailingDot) |
399 domain = domain.replace(/\.+$/, ""); | 397 domain = domain.replace(/\.+$/, ""); |
400 if (domain == "") | 398 if (domain == "") |
401 continue; | 399 continue; |
402 | 400 |
403 let include; | 401 let include; |
404 if (domain[0] == "~") | 402 if (domain[0] == "~") |
405 { | 403 { |
406 include = false; | 404 include = false; |
407 domain = domain.substr(1); | 405 domain = domain.substr(1); |
408 } | 406 } |
409 else | 407 else |
410 { | 408 { |
411 include = true; | 409 include = true; |
412 hasIncludes = true; | 410 hasIncludes = true; |
413 } | 411 } |
414 | 412 |
415 if (!domains) | 413 if (!domains) |
416 domains = Object.create(null); | 414 domains = new Map(); |
417 | 415 |
418 domains[domain] = include; | 416 domains.set(domain, include); |
419 } | 417 } |
420 if (domains) | 418 if (domains) |
421 domains[""] = !hasIncludes; | 419 domains.set("", !hasIncludes); |
422 } | 420 } |
423 | 421 |
424 this.domainSource = null; | 422 this.domainSource = null; |
425 } | 423 } |
426 | 424 |
427 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); | 425 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); |
428 return this.domains; | 426 return this.domains; |
429 }, | 427 }, |
430 | 428 |
431 /** | 429 /** |
(...skipping 19 matching lines...) Expand all Loading... |
451 return false; | 449 return false; |
452 } | 450 } |
453 | 451 |
454 // If no domains are set the rule matches everywhere | 452 // If no domains are set the rule matches everywhere |
455 if (!this.domains) | 453 if (!this.domains) |
456 return true; | 454 return true; |
457 | 455 |
458 // If the document has no host name, match only if the filter | 456 // If the document has no host name, match only if the filter |
459 // isn't restricted to specific domains | 457 // isn't restricted to specific domains |
460 if (!docDomain) | 458 if (!docDomain) |
461 return this.domains[""]; | 459 return this.domains.get(""); |
462 | 460 |
463 if (this.ignoreTrailingDot) | 461 if (this.ignoreTrailingDot) |
464 docDomain = docDomain.replace(/\.+$/, ""); | 462 docDomain = docDomain.replace(/\.+$/, ""); |
465 docDomain = docDomain.toUpperCase(); | 463 docDomain = docDomain.toUpperCase(); |
466 | 464 |
467 while (true) | 465 while (true) |
468 { | 466 { |
469 if (docDomain in this.domains) | 467 let isDomainIncluded = this.domains.get(docDomain); |
470 return this.domains[docDomain]; | 468 if (typeof isDomainIncluded != "undefined") |
| 469 return isDomainIncluded; |
471 | 470 |
472 let nextDot = docDomain.indexOf("."); | 471 let nextDot = docDomain.indexOf("."); |
473 if (nextDot < 0) | 472 if (nextDot < 0) |
474 break; | 473 break; |
475 docDomain = docDomain.substr(nextDot + 1); | 474 docDomain = docDomain.substr(nextDot + 1); |
476 } | 475 } |
477 return this.domains[""]; | 476 return this.domains.get(""); |
478 }, | 477 }, |
479 | 478 |
480 /** | 479 /** |
481 * Checks whether this filter is active only on a domain and its subdomains. | 480 * Checks whether this filter is active only on a domain and its subdomains. |
482 * @param {string} docDomain | 481 * @param {string} docDomain |
483 * @return {boolean} | 482 * @return {boolean} |
484 */ | 483 */ |
485 isActiveOnlyOnDomain(docDomain) | 484 isActiveOnlyOnDomain(docDomain) |
486 { | 485 { |
487 if (!docDomain || !this.domains || this.domains[""]) | 486 if (!docDomain || !this.domains || this.domains.get("")) |
488 return false; | 487 return false; |
489 | 488 |
490 if (this.ignoreTrailingDot) | 489 if (this.ignoreTrailingDot) |
491 docDomain = docDomain.replace(/\.+$/, ""); | 490 docDomain = docDomain.replace(/\.+$/, ""); |
492 docDomain = docDomain.toUpperCase(); | 491 docDomain = docDomain.toUpperCase(); |
493 | 492 |
494 for (let domain in this.domains) | 493 for (let [domain, isIncluded] of this.domains) |
495 { | 494 { |
496 if (this.domains[domain] && domain != docDomain) | 495 if (isIncluded && domain != docDomain) |
497 { | 496 { |
498 if (domain.length <= docDomain.length) | 497 if (domain.length <= docDomain.length) |
499 return false; | 498 return false; |
500 | 499 |
501 if (!domain.endsWith("." + docDomain)) | 500 if (!domain.endsWith("." + docDomain)) |
502 return false; | 501 return false; |
503 } | 502 } |
504 } | 503 } |
505 | 504 |
506 return true; | 505 return true; |
507 }, | 506 }, |
508 | 507 |
509 /** | 508 /** |
510 * Checks whether this filter is generic or specific | 509 * Checks whether this filter is generic or specific |
511 * @return {boolean} | 510 * @return {boolean} |
512 */ | 511 */ |
513 isGeneric() | 512 isGeneric() |
514 { | 513 { |
515 return !(this.sitekeys && this.sitekeys.length) && | 514 return !(this.sitekeys && this.sitekeys.length) && |
516 (!this.domains || this.domains[""]); | 515 (!this.domains || this.domains.get("")); |
517 }, | 516 }, |
518 | 517 |
519 /** | 518 /** |
520 * See Filter.serialize() | 519 * See Filter.serialize() |
521 * @inheritdoc | 520 * @inheritdoc |
522 */ | 521 */ |
523 serialize(buffer) | 522 serialize(buffer) |
524 { | 523 { |
525 if (this._disabled || this._hitCount || this._lastHit) | 524 if (this._disabled || this._hitCount || this._lastHit) |
526 { | 525 { |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 */ | 1019 */ |
1021 function ElemHideEmulationFilter(text, domains, selector) | 1020 function ElemHideEmulationFilter(text, domains, selector) |
1022 { | 1021 { |
1023 ElemHideBase.call(this, text, domains, selector); | 1022 ElemHideBase.call(this, text, domains, selector); |
1024 } | 1023 } |
1025 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1024 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
1026 | 1025 |
1027 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1026 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
1028 type: "elemhideemulation" | 1027 type: "elemhideemulation" |
1029 }); | 1028 }); |
OLD | NEW |