Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 */ | 419 */ |
420 function hideIfMatches(match, selector, searchSelector) | 420 function hideIfMatches(match, selector, searchSelector) |
421 { | 421 { |
422 if (searchSelector == null) | 422 if (searchSelector == null) |
423 searchSelector = selector; | 423 searchSelector = selector; |
424 | 424 |
425 let callback = () => | 425 let callback = () => |
426 { | 426 { |
427 for (let element of document.querySelectorAll(searchSelector)) | 427 for (let element of document.querySelectorAll(searchSelector)) |
428 { | 428 { |
429 if (match(element)) | 429 let closest = element.closest(selector); |
430 { | 430 if (closest && match(element, closest)) |
431 let closest = element.closest(selector); | 431 hideElement(closest); |
432 if (closest) | |
433 hideElement(closest); | |
434 } | |
435 } | 432 } |
436 }; | 433 }; |
437 new MutationObserver(callback) | 434 new MutationObserver(callback) |
438 .observe(document, {childList: true, characterData: true, subtree: true}); | 435 .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(); | 436 callback(); |
440 } | 437 } |
441 | 438 |
442 /** | 439 /** |
443 * Hides any HTML element or one of its ancestors matching a CSS selector if | 440 * Hides any HTML element or one of its ancestors matching a CSS selector if |
444 * the text content of the element contains a given string. | 441 * the text content of the element contains a given string. |
445 * | 442 * |
446 * @param {string} search The string to look for in HTML elements. If the | 443 * @param {string} search The string to look for in HTML elements. If the |
447 * string begins and ends with a slash (<code>/</code>), the text in between | 444 * string begins and ends with a slash (<code>/</code>), the text in between |
448 * is treated as a regular expression. | 445 * is treated as a regular expression. |
(...skipping 25 matching lines...) Expand all Loading... | |
474 * for it to be hidden. | 471 * for it to be hidden. |
475 * @param {?string} [searchSelector] The CSS selector that an HTML element | 472 * @param {?string} [searchSelector] The CSS selector that an HTML element |
476 * containing the given string must match. Defaults to the value of the | 473 * containing the given string must match. Defaults to the value of the |
477 * <code>selector</code> argument. | 474 * <code>selector</code> argument. |
478 */ | 475 */ |
479 function hideIfContainsVisibleText(search, selector, searchSelector = null) | 476 function hideIfContainsVisibleText(search, selector, searchSelector = null) |
480 { | 477 { |
481 /** | 478 /** |
482 * Determines if the text inside the element is visible. | 479 * Determines if the text inside the element is visible. |
483 * @param {Element} element The element we are checking. | 480 * @param {Element} element The element we are checking. |
484 * @param {?CSSStyleDeclaration} [style] The computed style of element. If | 481 * @param {?CSSStyleDeclaration} style The computed style of element. If |
485 * falsey it will be queried. | 482 * 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. | 483 * @returns {bool} Whether the text is visible. |
487 */ | 484 */ |
488 function isTextVisible(element, style) | 485 function isTextVisible(element, style) |
489 { | 486 { |
490 if (!style) | 487 if (!style) |
491 style = window.getComputedStyle(element); | 488 style = window.getComputedStyle(element); |
492 | 489 |
493 if (style.getPropertyValue("opacity") == "0") | 490 if (style.getPropertyValue("opacity") == "0") |
494 return false; | 491 return false; |
495 if (style.getPropertyValue("font-size") == "0px") | 492 if (style.getPropertyValue("font-size") == "0px") |
496 return false; | 493 return false; |
497 if (style.getPropertyValue("color") == | 494 |
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")) | 495 let color = style.getPropertyValue("color"); |
496 // if color is transparent... | |
497 if (color == "rgba(0, 0, 0, 0)") | |
499 return false; | 498 return false; |
499 if (style.getPropertyValue("background-color") == color) | |
500 return false; | |
500 | 501 |
501 return true; | 502 return true; |
503 } | |
504 | |
505 /** | |
506 * Check if an element is visible | |
507 * @param {Element} element The element to check visibility of. | |
508 * @param {?CSSStyleDeclaration} style The computed style of element. If | |
509 * falsey it will be queried. | |
510 * @param {?Element} closest The closest parent to reach. | |
511 * @return {bool} Whether the element is visible. | |
512 */ | |
513 function isVisible(element, style, closest) | |
514 { | |
515 if (!style) | |
516 style = window.getComputedStyle(element); | |
517 | |
518 if (style.getPropertyValue("display") == "none") | |
519 return false; | |
520 let visibility = style.getPropertyValue("visibility"); | |
521 if (visibility == "hidden" || visibility == "collapse") | |
522 return false; | |
523 | |
524 if (!closest || element == closest) | |
525 return true; | |
526 | |
527 let parent = element.parentElement; | |
528 if (!parent) | |
529 return true; | |
530 | |
531 return isVisible(parent, null, closest); | |
502 } | 532 } |
503 | 533 |
504 /** | 534 /** |
505 * Returns the visible text content from an element and its descendants. | 535 * Returns the visible text content from an element and its descendants. |
506 * @param {Element} element The element whose visible text we want. | 536 * @param {Element} element The element whose visible text we want. |
537 * @param {Element} closest The closest parent to reach while checking | |
538 * for visibility. | |
507 * @returns {string} The text that is visible. | 539 * @returns {string} The text that is visible. |
508 */ | 540 */ |
509 function getVisibleContent(element) | 541 function getVisibleContent(element, closest) |
510 { | 542 { |
511 let style = window.getComputedStyle(element); | 543 let style = window.getComputedStyle(element); |
512 if (style.getPropertyValue("display") == "none") | 544 if (!isVisible(element, style, closest)) |
513 return ""; | |
514 let visibility = style.getPropertyValue("visibility"); | |
515 if (visibility == "hidden" || visibility == "collapse") | |
516 return ""; | 545 return ""; |
517 | 546 |
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 = ""; | 547 let text = ""; |
519 for (let node of element.childNodes) | 548 for (let node of element.childNodes) |
520 { | 549 { |
521 switch (node.nodeType) | 550 switch (node.nodeType) |
522 { | 551 { |
523 case Node.ELEMENT_NODE: | 552 case Node.ELEMENT_NODE: |
524 text += getVisibleContent(node); | 553 text += getVisibleContent(node, element); |
525 break; | 554 break; |
526 case Node.TEXT_NODE: | 555 case Node.TEXT_NODE: |
527 if (isTextVisible(element, style)) | 556 if (isTextVisible(element, style)) |
528 text += node.nodeValue; | 557 text += node.nodeValue; |
529 break; | 558 break; |
530 } | 559 } |
531 } | 560 } |
532 return text; | 561 return text; |
533 } | 562 } |
534 | 563 |
535 let re = toRegExp(search); | 564 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.
| |
536 | 565 |
537 hideIfMatches(element => re.test(getVisibleContent(element)), | 566 hideIfMatches( |
538 selector, searchSelector); | 567 (element, closest) => re.test(getVisibleContent(element, closest)), |
568 selector, searchSelector); | |
539 } | 569 } |
540 | 570 |
541 exports["hide-if-contains-visible-text"] = hideIfContainsVisibleText; | 571 exports["hide-if-contains-visible-text"] = hideIfContainsVisibleText; |
542 | 572 |
543 /** | 573 /** |
544 * Hides any HTML element or one of its ancestors matching a CSS selector if | 574 * Hides any HTML element or one of its ancestors matching a CSS selector if |
545 * the text content of the element contains a given string and, optionally, if | 575 * the text content of the element contains a given string and, optionally, if |
546 * the element's computed style contains a given string. | 576 * the element's computed style contains a given string. |
547 * | 577 * |
548 * @param {string} search The string to look for in HTML elements. If the | 578 * @param {string} search The string to look for in HTML elements. If the |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
990 | 1020 |
991 args[0] = url.href; | 1021 args[0] = url.href; |
992 } | 1022 } |
993 | 1023 |
994 return fetch_.apply(this, args); | 1024 return fetch_.apply(this, args); |
995 }; | 1025 }; |
996 } | 1026 } |
997 | 1027 |
998 exports["strip-fetch-query-parameter"] = makeInjector(stripFetchQueryParameter, | 1028 exports["strip-fetch-query-parameter"] = makeInjector(stripFetchQueryParameter, |
999 toRegExp, regexEscape); | 1029 toRegExp, regexEscape); |
LEFT | RIGHT |