Opened 4 years ago

Last modified 2 years ago

#3143 closed change

Add polyfill for `:has()` CSS4 pseudo-selector to element hiding filters — at Version 24

Reported by: greiner Assignee: fhd
Priority: P2 Milestone:
Module: Core Keywords:
Cc: mapx, Lain_13, sebastian, fhd, mario, kzar, rach, arthur, sergz, oleksandr Blocked By: #4394, #4726, #4962
Blocking: #2360 Platform: Unknown / Cross platform
Ready: yes Confidential: no
Tester: Unknown Verified working: no
Review URL(s):

https://codereview.adblockplus.org/29383960/
https://codereview.adblockplus.org/29464696/

Description (last modified by fhd)

Background

(taken from original description in #2360 about hiding elements by selecting their child elements)

Currently, there's no way to hide an element on a page dependent on its children. This proposed solution is based on existing CSS functionality, so it will be possible to bind an observer to the document to check for new parent nodes and bind another observer object to them to check for changes within only these particular nodes in case specific child node will be added. Over time it will be possible to completely disable such functionality due to native support for CSS4 selectors in newer browser versions.

It may be possible to look at the jQuery code for this functionality since they supported :has() pseudo-selector in their selectors long before it was even added into the CSS4 drafts.

Generally, this proposal has similar issues as CSS property filters such as requiring to hide elements manually and to observe the page for changes at runtime.

:has() and CSS property filters have to work in conjunction, therefore they need to be stored in the same filter class (see #4394). In addition, we will probably have to change the way CSS property filters work: Currently we eventually generate standard CSS rules for them, which are then being applied by the browser. For :has(), we have to apply the rules manually.

What to change

  • Allow :has() to be specified within element hiding filter CSS selectors
  • Determine whether :has() pseudo-selector is supported natively (document.querySelector("abp:has(abp)") throws a syntax error exception if :has() is not supported)
  • Otherwise detect the pattern PREFIX:has(SELECTOR)SUFFIX inside the selector string and run the following logic upon encountering it:
    • Extract selectors from selector string because it might contain multiple separate selectors
    • For each element a matching PREFIX in selector
      • Check whether SELECTOR matches any of a's child elements
      • If so, hide all elements matching SUFFIX inside a or a if SUFFIX does not exist
  • Make sure :has() and -abp-properties works in conjunction

Optional changes

  • Recursively resolve further instances of :has() inside SELECTOR and SUFFIX using the same logic (e.g. to resolve abc:has(def:has(ghi):has(jkl)) mno:has(pqr))
  • Observe DOM changes to apply filters to dynamically added/modified elements

References

Change History (24)

comment:1 Changed 4 years ago by greiner

  • Type changed from defect to change

comment:2 Changed 4 years ago by greiner

  • Blocking 2360 added

comment:3 Changed 4 years ago by mapx

  • Cc mapx Lain_13 added

comment:4 Changed 3 years ago by fhd

  • Owner set to fhd

I'll have a go at this one.

comment:5 Changed 3 years ago by fhd

  • Priority changed from Unknown to P2

comment:6 follow-up: Changed 3 years ago by Lain_13

I think it's worth mentioning that :has() selector must work in combination with -abp-properties. So, filter like site.name##.block:has([-abp-properties="background: yellow"]) must hide all elements of class "block" with anything with word "yellow" in a "background" property inside of them.

Last edited 3 years ago by Lain_13 (previous) (diff)

comment:7 Changed 3 years ago by kzar

  • Cc sebastian fhd added
  • Owner changed from fhd to kzar

comment:8 Changed 3 years ago by kzar

  • Description modified (diff)

comment:9 Changed 3 years ago by mapx

"waiting for #2388 to be closed probably makes the most sense to get the necessary architecture in place first"

#2388 ==> still opened #2398 ==> still opened #2402 (unit tests)

(fhd comment: Given how CSS property filters support has already landed in Firefox - how about closing this one (and #2388) and removing #2402 as a dependency? )

comment:10 Changed 3 years ago by kzar

  • Blocked By 2388 removed

Yea I think you're right, I don't think this is blocked by #2388 any more. I'll remove that as blocking now.

comment:11 in reply to: ↑ 6 Changed 3 years ago by mapx

Replying to Lain_13:

I think it's worth mentioning that :has() selector must work in combination with -abp-properties. So, filter like site.name##.block:has([-abp-properties="background: yellow"]) must hide all elements of class "block" with anything with word "yellow" in a "background" property inside of them.

it's exactly the last trick FB used to defeat the various userscripts (using css ::after)

comment:12 Changed 3 years ago by kzar

  • Cc mario added

comment:13 Changed 3 years ago by kzar

  • Cc kzar added
  • Owner kzar deleted

(I have had nearly no chance to look at this so far and am on vacation next week. Will reassign myself again when I have time if no one else has picked it up.)

comment:14 Changed 3 years ago by ethaniel

Can't wait for this ticket to be resolved. Yandex is using every possibility to evade the block. Still seeing ads.

comment:15 Changed 3 years ago by fhd

  • Owner set to fhd

With Dave gone for a while, I'll pick this up again, this time for real :)

I guess I still won't find enough time to finish it, but there's some ground work to be done I can get out of the way at the least, I'll create a blocking issue for that soon.

comment:16 Changed 3 years ago by fhd

  • Blocked By 4394 added

comment:17 Changed 3 years ago by fhd

  • Description modified (diff)

I've created #4394 for the ground work I was talking about. I'll take care of that first.

I realised that in order for :has() and CSS property filters to work in conjunction (which I also see as a must), we'll have to change the way CSS property filters are being applied somewhat fundamentally. I've updated the description a bit to reflect that.

comment:18 Changed 3 years ago by rach

  • Cc rach added

comment:19 Changed 3 years ago by fhd

  • Blocked By 4658 added

comment:20 Changed 3 years ago by fhd

  • Blocked By 4658 removed

comment:21 Changed 3 years ago by arthur

  • Cc arthur added

comment:22 Changed 3 years ago by fhd

  • Blocked By 4726 added

comment:23 Changed 3 years ago by hfiguiere

  • Blocked By 4962 added

comment:24 Changed 3 years ago by hfiguiere

  • Review URL(s) modified (diff)
Note: See TracTickets for help on using tickets.