Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new pseudo-class ':others()' #164

Open
slavaleleka opened this issue Feb 9, 2023 · 14 comments
Open

Implement new pseudo-class ':others()' #164

slavaleleka opened this issue Feb 9, 2023 · 14 comments

Comments

@slavaleleka
Copy link
Contributor

@iSmokeMid69 commented on Thu Feb 09 2023

Issue Details

Ublock Has :others() Operator..Which Keep Only A Selected Element Of A Page And Remove Everything Else..This Is Very Useful For Link Shortener Sites

Details -

subject:others()

Experimental.

Description: Target all elements outside than the currently selected set of elements.
Chainable: Yes.
subject: Can be a plain CSS selector, or a procedural cosmetic filter.
Examples:
    twitter.com##:matches-path(/^/home/) [data-testid="primaryColumn"]:others()
    nature.com##:matches-path(/^/articles//) :is(.c-breadcrumbs,.c-article-main-column):others()

Introduced in uBO 1.41.1b2

For any element feeding into others(), the resultset of the others() operator will include everything else except:

the descendants of a subject element
the ancestors of a subject element

The resultset will contains the siblings of a subject element except when those siblings are either a descendant or ancestor of another subject element.

Though this operator is unlikely to be used in default lists, it opens the door to create specialized filter lists which purpose is some sort of "reader mode", where everything else than a selected set of elements are hidden from view.

Related discussion:

https://www.reddit.com/r/uBlockOrigin/comments/slyjzp/

Proposed solution

No response

Alternative solution

No response

@ameshkov
Copy link
Member

ameshkov commented Feb 13, 2023

Sounds as if it should be handled via rules conversion isn't it?

  • [data-testid="primaryColumn"]:others() -> :not([data-testid="primaryColumn"])

@ameshkov
Copy link
Member

ameshkov commented Feb 13, 2023

I might be missing something, but :not(selector) seems to be exactly the same thing as selector:others().

As I recall, :not is not fully supported in uBO, maybe that's the reason why a new modifier was required.

@MasterKia
Copy link

AFAIK uBO doesn't do :remove() on the elements.

@ameshkov
Copy link
Member

I assumed it does from the issue text:

Ublock Has :others() Operator..Which Keep Only A Selected Element Of A Page And Remove Everything Else..This Is Very Useful For Link Shortener Sites

@MasterKia
Copy link

I'm sure he meant "hide".

Ublock Has :others() Operator..Which Keep Only A Selected Element Of A Page And Remove Hide Everything Else..This Is Very Useful For Link Shortener Sites

@ameshkov
Copy link
Member

Ah, then it's even easier, { remove: true } is not needed.

@krystian3w
Copy link

krystian3w commented Feb 14, 2023

#164 (comment) / #164 (comment): :not(bla-bla-car) don't longer hide parents/siblinghood/childs in CSS?

<body>                         <!-- A simple ":not" should not hide me -->

    <p> uneeded text </p>         <!-- it should be hidden due bla-bla-car:others() -->

    <div>                         <!-- A simple ":not" should not hide me -->

        <bla-bla-car> 

            don't hide my parent "div" and "grandparent" body!

            <p> text </p>               <!-- A simple ":not" should not hide me -->

            <div>                       <!-- A simple ":not" should not hide me -->

                <button type="button"> click </button>   <!-- A simple ":not" should not hide me -->

            </div>

        </bla-bla-car>

        <p> uneeded text </p>       <!-- it should be hidden due bla-bla-car:others() -->

    </div>

    <p> uneeded text </p>         <!-- it should be hidden due bla-bla-car:others() -->

</body>

image

:others() is written to correctly omit hiding the parents (without listing them).

As for me, rewriting to pure CSS would require scanning the entire DOM tree. So that the body and other parents (with younger "family") of each element are listed after the comma(s) in the :not CSS4: #164 (comment)

@ameshkov
Copy link
Member

Ah, now it makes perfect sense to me, thank you!

@ameshkov
Copy link
Member

ameshkov commented Feb 14, 2023

Then I guess it can be rewritten this way, right?

[data-testid="primaryColumn"]:others() -> :not(:has([data-testid="primaryColumn"]))

edit: ah, nope, it cannot, won't cover the elements inside [data-testid="primaryColumn"]

@u-RraaLL
Copy link

For only showing .TimelineItem (comments here), this would also work on uBO (just like ##.TimelineItem:others()), but doesn't on Adguard (hides everything, even itself).

##:not(.TimelineItem *):not(:has(.TimelineItem *))

@slavaleleka
Copy link
Contributor Author

not yet sir

@BlazeFTL
Copy link

BlazeFTL commented Nov 4, 2023

Any progress update on this ?🙃

@slavaleleka
Copy link
Contributor Author

@BlazeFTL it hasn't been yet planned to be implemented soon

@krystian3w
Copy link

krystian3w commented Nov 7, 2023

With CSS4 should run at page:

body :not(.TimelineItem, .TimelineItem *, :has(.TimelineItem)) { display: none !important }

/* First protect element, second child, last one 'root'. */

body :not([data-testid="primaryColumn"], [data-testid="primaryColumn"] *, :has([data-testid="primaryColumn"])) { display: none !important }

Gaps gone, looks works based on ExtCSS library.

It remains to be assessed whether it is worth replacing comma elements to three ":not" and how much more resource-intensive it is than the JavaScript version.



In native CSS3 this seems to be the closest:

https://caniuse.com/css-not-sel-list (Chromium 88+, Firefox 84+, Safari 9+)

body :not(.TimelineItem, .TimelineItem *, [data-testid="primaryColumn"], [data-testid="primaryColumn"] *) {
    visibility: hidden !important;
  /* at own risk in huge DOM tree:
    padding: 0 !important;
    margin: 0 !important;
    height: 0 !important */
}
:root [data-testid="primaryColumn"],
:root .TimelineItem { visibility: visible !important }

with little chance of hiding gaps left by invisible elements.

RraaLL idea is not CSS "selector" (that is procedural selector - works in legacy browsers or with outdated uBo 1.45+ to 1.54 in modern browsers) so do not works in Chrome 105-109 and Firefox 115 as raw CSS (latter I can check in Safari 17.2, Firefox Nightly and Chrome Canary).



Hiding on Chrome 1*-87, Firefox 1*-83, Safari 1*-8 may need (legacy browsers - mostly CSS 2.1):
:root { visibility: hidden !important }
:root [data-testid="primaryColumn"],
:root .TimelineItem { visibility: visible !important }

(With harder implementation hide gaps).

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

No branches or pull requests

8 participants
@ameshkov @MasterKia @krystian3w @zzebrum @slavaleleka @u-RraaLL @BlazeFTL and others