Skip to content

Combining procedural selector :has() and :style() #382

@shesek

Description

@shesek

This is a very useful combination, but it seems like they don't like working together?

Activity

uBlock-user

uBlock-user commented on Jan 18, 2019

@uBlock-user
Contributor

Put back the template and fill it if you want to file a bug.

gorhill

gorhill commented on Jan 18, 2019

@gorhill
Member

I reopen because I am aware of this, this is a TODO. Many AdGuard filters are discarded because of this. Repro steps:

  • Open the logger
  • Select "All" in the logger
  • Set filter expression to "cosmetic filter" in the logger
  • Enable (or force a reload of) AdGuard Base Filters

Result: the output of the logger will show many such cosmetic filters being rejected.

shesek

shesek commented on Jan 19, 2019

@shesek
Author

Apologies for not properly using the template, I wasn't really sure whether its a bug report or I'm simply missing something. Posting this to /r/uBlockOrigin as a question first would probably be a better way to go at this. Sorry!

I'm not sure whether uBlockOrigin cares about enabling non-ad-blocking use-cases, but FWIW, what I was trying to do is reduce the visibility of facebook posts that contain a certain hashtag:

facebook.com##div[role=article]:has(.userContentWrapper .userContent a[href^="/hashtag/XYZ?"]):style(opacity:0.5)
krystian3w

krystian3w commented on Jan 24, 2019

@krystian3w

As for me, it's a bit of a strained example, you can do something like this with ViolentMonkey / GreasyMonkey / TamperMonkey also.

Grossdm

Grossdm commented on Feb 14, 2019

@Grossdm

Has :style() ever been chainable (allowed on procedural cosmetic filters)? I thought that it was, and I've struggled in creating some filters recently.

If it is at all feasible, implementing this would be useful.

A common need arises in unsticking headers (very helpful for mobile browsing).

If I can find the correct DOM node with the element selector, often the selector is one that seems likely either to not apply on other pages of the site or to not last very long (i.e., small site changes likely to break the selector).

Typically, I can create a procedural selector with either:

  1. :has() because the "header" (only a div, not a header tag) contains a class named similar to "nav".

  2. :matches-css() in some easy cases because the stuck header is simply styled position: fixed, but unfortunately lacks an id or class that a regular CSS selector could match.

Thanks for everyone's work on uBlock Origin!

yourduskquibbles

yourduskquibbles commented on Feb 14, 2019

@yourduskquibbles

Has :style() ever been chainable (allowed on procedural cosmetic filters)? I thought that it was, and I've struggled in creating some filters recently.

Not that I've found. See gorhill's first comment on it that I could find - gorhill/uBlock#781 (comment)

I would also find this useful (and have a real use case I would use this on as well)

ghost changed the title [-]Combining :has() and :style()[/-] [+]Combining procedural selector :has() and :style()[/+] on Nov 26, 2019

32 remaining items

gorhill

gorhill commented on Sep 14, 2020

@gorhill
Member

While investigating, it looks like there is a regression. Trying to find existing filter, this one in uBlock filters:

enterinit.com##*::selection:style(background-color:#338FFF!important)

The style is no longer applied, the change here causes uBO to always apply display: none !important when there is a pseudo-element.

yourduskquibbles

yourduskquibbles commented on Oct 5, 2020

@yourduskquibbles

@gorhill I think there may be another case where this doesn't work consistently - when filters targeting multiple DOM elements are consolidated into one filter and one of them includes the :upward(n) uBO extended filter syntax.

test link: https://www.nytimes.com/live/2020/10/01/us/trump-vs-biden

After scrolling down the page a bit, try to create the following consolidated filters (applying CSS to three elements with one filter) using the element picker:

  1. The filter below does NOT work to pin the multiple floating header components (when :upward(n) is in the first or middle consolidated filter position element picker won't highlight elements and won't allow create):
    ###NYT_TOP_BANNER_REGION:upward(1), #NYT_TOP_BANNER_REGION, #NYT_TOP_BANNER_REGION > div > .interactive-size-medium.interactive-content:style(position: static !important;)

nytimes01

  1. But the filter below WORKS to pin the multiple floating header components (when :upward(n) is in the last consolidated filter position):
    ###NYT_TOP_BANNER_REGION, #NYT_TOP_BANNER_REGION > div > .interactive-size-medium.interactive-content, #NYT_TOP_BANNER_REGION:upward(1):style(position: static !important;)

nytimes02

The filter that you can create with element picker also works on page reload, but the non-working filter doesn't work even if you add it to My Filters without going through element picker.

Tested on both firefox and chrome latest uBO dev builds.

gorhill

gorhill commented on Oct 5, 2020

@gorhill
Member

@yourduskquibbles You can't use a procedural operator in a list of selectors, you will need to separate #NYT_TOP_BANNER_REGION:upward(1) from the rest.

When you use a procedural operator in a selector, the whole selector is parsed as a procedural one, and in such case this results in an invalid selector when using a comma-separated list of CSS selector. When not using a procedural operator, you end up with a valid list of plain CSS selectors and uBO does not try to parse this, it just declaratively inject the style.

Note that the second form works because the prepended selector passes the querySelector() test, #NYT_TOP_BANNER_REGION, #NYT_TOP_BANNER_REGION > div > .interactive-size-medium.interactive-content, #NYT_TOP_BANNER_REGION is a valid plain CSS selector, it can be querySelector-ed.

In the first form, uBO tries to test , #NYT_TOP_BANNER_REGION, #NYT_TOP_BANNER_REGION > div > .interactive-size-medium.interactive-content against querySelector, and this fails.

krystian3w

krystian3w commented on Oct 5, 2020

@krystian3w

AdGuard maybe support:

example.*#$#body:has(div[style]), html:has(div[style]) { overflow: visible !important }

but upward/xpath now supported only at end of filter due Sizzle (jQuery?) limitation in own environment.

added a commit that references this issue on Oct 6, 2020
gorhill

gorhill commented on Oct 6, 2020

@gorhill
Member

Actually, I need to investigate why the first form does not show as an error, I would have expected so.

gorhill

gorhill commented on Oct 6, 2020

@gorhill
Member

In the next dev build, following selector will be marked and rejected as erroneous:

*###a:upward(1), #b:style(position: static !important;)

While the following one will be accepted as valid:

*###a, #b:upward(1):style(position: static !important;)

However, the last one has to be understood as result of #a, #b being fed to :upward(1):style(...); not as #a:style(...) and #b:upward(1):style(...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfixedissue has been addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @gorhill@mvastola@Grossdm@shesek@mapx-

        Issue actions

          Combining procedural selector :has() and :style() · Issue #382 · uBlockOrigin/uBlock-issues