Left: | ||
Right: |
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 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 } | 401 } |
402 }); | 402 }); |
403 } | 403 } |
404 | 404 |
405 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, | 405 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, |
406 toRegExp, regexEscape, | 406 toRegExp, regexEscape, |
407 hideElement); | 407 hideElement); |
408 | 408 |
409 /** | 409 /** |
410 * Hides any HTML element or one of its ancestors matching a CSS selector if | 410 * Hides any HTML element or one of its ancestors matching a CSS selector if |
411 * it matches the provided condition. | |
412 * | |
413 * @param {function} match The function that provides the matching condition. | |
414 * @param {string} selector The CSS selector that an HTML element must match | |
415 * for it to be hidden. | |
416 * @param {?string} [searchSelector] The CSS selector that an HTML element | |
417 * containing the given string must match. Defaults to the value of the | |
418 * <code>selector</code> argument. | |
419 */ | |
420 function hideIfMatches(match, selector, searchSelector) | |
421 { | |
422 if (searchSelector == null) | |
423 searchSelector = selector; | |
424 | |
425 let callback = () => | |
426 { | |
427 for (let element of document.querySelectorAll(searchSelector)) | |
428 { | |
429 if (match(element)) | |
430 { | |
431 let closest = element.closest(selector); | |
432 if (closest) | |
433 hideElement(closest); | |
434 } | |
435 } | |
436 }; | |
437 new MutationObserver(callback) | |
438 .observe(document, {childList: true, characterData: true, subtree: true}); | |
a.giammarchi
2019/04/26 13:33:58
I might make a similar observation we had before (
hub
2019/04/27 17:32:05
The current code is just refactoring of the other
a.giammarchi
2019/04/29 07:27:25
Acknowledged.
hub
2019/04/29 15:20:55
BTW I filed https://gitlab.com/eyeo/adblockplus/ad
| |
439 callback(); | |
440 } | |
441 | |
442 /** | |
443 * Hides any HTML element or one of its ancestors matching a CSS selector if | |
411 * the text content of the element contains a given string. | 444 * the text content of the element contains a given string. |
412 * | 445 * |
413 * @param {string} search The string to look for in HTML elements. If the | 446 * @param {string} search The string to look for in HTML elements. If the |
414 * string begins and ends with a slash (<code>/</code>), the text in between | 447 * string begins and ends with a slash (<code>/</code>), the text in between |
415 * is treated as a regular expression. | 448 * is treated as a regular expression. |
416 * @param {string} selector The CSS selector that an HTML element must match | 449 * @param {string} selector The CSS selector that an HTML element must match |
417 * for it to be hidden. | 450 * for it to be hidden. |
418 * @param {string?} [searchSelector] The CSS selector that an HTML element | 451 * @param {?string} [searchSelector] The CSS selector that an HTML element |
419 * containing the given string must match. Defaults to the value of the | 452 * containing the given string must match. Defaults to the value of the |
420 * <code>selector</code> argument. | 453 * <code>selector</code> argument. |
421 */ | 454 */ |
422 function hideIfContains(search, selector = "*", searchSelector = null) | 455 function hideIfContains(search, selector = "*", searchSelector = null) |
423 { | 456 { |
424 if (searchSelector == null) | 457 let re = toRegExp(search); |
425 searchSelector = selector; | 458 |
459 hideIfMatches(element => re.test(element.textContent), | |
460 selector, searchSelector); | |
461 } | |
462 | |
463 exports["hide-if-contains"] = hideIfContains; | |
464 | |
465 /** | |
466 * Hides any HTML element matching a CSS selector if the visible text content | |
467 * of the element contains a given string. | |
468 * | |
469 * @param {string} search The string to match to the visible text. Is considered | |
470 * visible text that isn't hidden by CSS properties or other means. | |
471 * If the string begins and ends with a slash (<code>/</code>), the | |
472 * text in between is treated as a regular expression. | |
473 * @param {string} selector The CSS selector that an HTML element must match | |
474 * for it to be hidden. | |
475 * @param {?string} [searchSelector] The CSS selector that an HTML element | |
476 * containing the given string must match. Defaults to the value of the | |
477 * <code>selector</code> argument. | |
478 */ | |
479 function hideIfContainsVisibleText(search, selector, searchSelector = null) | |
480 { | |
481 /** | |
482 * Determines if the text inside the element is visible. | |
483 * @param {Element} element The element we are checking. | |
484 * @param {?CSSStyleDeclaration} [style] The computed style of element. If | |
485 * falsey it will be queried. | |
a.giammarchi
2019/04/26 13:33:58
typo? did you mean `falsy` ?
hub
2019/04/27 17:32:05
Both are acceptable, and we use `falsey` elsewhere
a.giammarchi
2019/04/29 07:27:25
Acknowledged.
| |
486 * @returns {bool} Whether the text is visible. | |
487 */ | |
488 function isTextVisible(element, style) | |
489 { | |
490 if (!style) | |
491 style = window.getComputedStyle(element); | |
492 | |
493 if (style.getPropertyValue("opacity") == "0") | |
494 return false; | |
495 if (style.getPropertyValue("font-size") == "0px") | |
496 return false; | |
497 if (style.getPropertyValue("color") == | |
a.giammarchi
2019/04/26 13:33:57
shouldn't `color` be checked against `transparent`
hub
2019/04/27 17:32:05
good point. I knew there were things I'm missing.
| |
498 style.getPropertyValue("background-color")) | |
499 return false; | |
500 | |
501 return true; | |
502 } | |
503 | |
504 /** | |
505 * Returns the visible text content from an element and its descendants. | |
506 * @param {Element} element The element whose visible text we want. | |
507 * @returns {string} The text that is visible. | |
508 */ | |
509 function getVisibleContent(element) | |
510 { | |
511 let style = window.getComputedStyle(element); | |
512 if (style.getPropertyValue("display") == "none") | |
513 return ""; | |
514 let visibility = style.getPropertyValue("visibility"); | |
515 if (visibility == "hidden" || visibility == "collapse") | |
516 return ""; | |
517 | |
a.giammarchi
2019/04/26 13:51:06
shouldn't `clientWidth` and `clientHeight` be also
hub
2019/04/27 17:32:05
Good point. I'll look into it.
| |
518 let text = ""; | |
519 for (let node of element.childNodes) | |
520 { | |
521 switch (node.nodeType) | |
522 { | |
523 case Node.ELEMENT_NODE: | |
524 text += getVisibleContent(node); | |
525 break; | |
526 case Node.TEXT_NODE: | |
527 if (isTextVisible(element, style)) | |
528 text += node.nodeValue; | |
529 break; | |
530 } | |
531 } | |
532 return text; | |
533 } | |
426 | 534 |
427 let re = toRegExp(search); | 535 let re = toRegExp(search); |
a.giammarchi
2019/04/26 13:33:58
this feature is overall OK but I have one concern:
hub
2019/04/27 17:32:05
Whichever effect applies to the text with CSS, the
a.giammarchi
2019/04/29 07:27:25
If I understand correctly, we might check for "Ads
hub
2019/04/29 13:03:47
I see where this is going. Good point.
Because th
a.giammarchi
2019/04/29 15:31:10
Acknowledged.
| |
428 | 536 |
429 new MutationObserver(() => | 537 hideIfMatches(element => re.test(getVisibleContent(element)), |
430 { | 538 selector, searchSelector); |
431 for (let element of document.querySelectorAll(searchSelector)) | |
432 { | |
433 if (re.test(element.textContent)) | |
434 { | |
435 let closest = element.closest(selector); | |
436 if (closest) | |
437 hideElement(closest); | |
438 } | |
439 } | |
440 }) | |
441 .observe(document, {childList: true, characterData: true, subtree: true}); | |
442 } | 539 } |
443 | 540 |
444 exports["hide-if-contains"] = hideIfContains; | 541 exports["hide-if-contains-visible-text"] = hideIfContainsVisibleText; |
445 | 542 |
446 /** | 543 /** |
447 * Hides any HTML element or one of its ancestors matching a CSS selector if | 544 * Hides any HTML element or one of its ancestors matching a CSS selector if |
448 * the text content of the element contains a given string and, optionally, if | 545 * the text content of the element contains a given string and, optionally, if |
449 * the element's computed style contains a given string. | 546 * the element's computed style contains a given string. |
450 * | 547 * |
451 * @param {string} search The string to look for in HTML elements. If the | 548 * @param {string} search The string to look for in HTML elements. If the |
452 * string begins and ends with a slash (<code>/</code>), the text in between | 549 * string begins and ends with a slash (<code>/</code>), the text in between |
453 * is treated as a regular expression. | 550 * is treated as a regular expression. |
454 * @param {string} selector The CSS selector that an HTML element must match | 551 * @param {string} selector The CSS selector that an HTML element must match |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
893 | 990 |
894 args[0] = url.href; | 991 args[0] = url.href; |
895 } | 992 } |
896 | 993 |
897 return fetch_.apply(this, args); | 994 return fetch_.apply(this, args); |
898 }; | 995 }; |
899 } | 996 } |
900 | 997 |
901 exports["strip-fetch-query-parameter"] = makeInjector(stripFetchQueryParameter, | 998 exports["strip-fetch-query-parameter"] = makeInjector(stripFetchQueryParameter, |
902 toRegExp, regexEscape); | 999 toRegExp, regexEscape); |
OLD | NEW |