gorhill / uBlock

uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean.
GNU General Public License v3.0
46.44k stars 3.11k forks source link

Make element removal rules backwards/Chromium-compatible #3493

Closed anewuser closed 6 years ago

anewuser commented 6 years ago

@mapx- changed my rule in https://github.com/uBlockOrigin/uAssets/pull/1507 because apparently Chrome would just discard it.

I couldn't find any discussion about this. Have you considered parsing new rules such as

www.google.ca##^#hplogo

as

www.google.ca##^#hplogo
www.google.ca###hplogo

? That'd be useful for us to use ^ in filter lists while keeping compatibility with Chromium-based browsers.

mapx- commented 6 years ago

HTML filtering (##^) is supported only by Firefox 57+ https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#html-filters

https://github.com/gorhill/uBlock/issues/3069

gorhill commented 6 years ago

HTML filtering is not the same as cosmetic filtering, they are not semantically the same -- filtering the DOM is completely different than filtering the response data. Furthermore, for any issue, it's preferable to use a cosmetic filter when it works, because HTML filtering is only available on Firefox 57+.

anewuser commented 6 years ago

HTML filtering (##^) is supported only by Firefox 57+

That's what I meant. Since www.google.ca##^#hplogo only works on Firefox 57+, it could be interpreted as

www.google.ca##^#hplogo
www.google.ca###hplogo

So this element (included in the first plain HTML request) gets completely stripped on Firefox 57+ while still being hidden on older versions and browsers.

I know it can filter more than just <body> IDs and classes, but I'm talking about them specifically (example.org##^#test and example.org##.#test).

I understand if you prefer not to add this and keep using only cosmetic filters on official filters.

gorhill commented 6 years ago

Ok I understand your point. I need to ponder more about this.

gorhill commented 6 years ago

Well, for the specific case at hand, using a cosmetic filter is preferable even on Firefox, because Firefox already benefits from supporting user stylesheets. HTML filtering requires special code path to be taken, not worth it when a cosmetic filter works just fine. So for now I would need a better case to support implementing such fall back.

What is needed is an actual real world case for which removing an element is preferable to hiding it.

anewuser commented 6 years ago

Yes, I had mentioned in the original post (and then removed it to keep it concise) that my link isn't the best example, since HTML filtering on it just blocks the loading of a small image from the same domain.

If the static images hidden by certain cosmetic filters are larger or from third-party domains, though, it's preferable to remove the element altogether instead of downloading such hidden images in the background. I'll try to find some good example if you decide to keep this issue open.

However, if there's the expectation that toggling no-cosmetic-filtering: to true will show all non-dynamic content hidden or filtered out by subscription lists, HTML filtering for structural elements like div, p etc. would have to be turned off too when this setting is used.

anewuser commented 6 years ago

Ah, I just remembered this, which has larger images (although also from the same domain): https://github.com/AdguardTeam/AdguardFilters/pull/10140

moviechat.org changed the path of its banners from moviechat.org/images/affiliates/ (previously blocked by AdGuard) to moviechat.org/images/aff/, while keeping the same CSS class for the ads parent element.

The result of this was that the banners started being loaded in the background, while still being hidden by AdGuard and EasyList cosmetic rules. This was fixed only when I noticed it by watching the logger and reported it to them.

If moviechat.org changes the path of banners again, they'll once again start being downloaded in the background until someone notices it (and since subscription lists hide the parent element, you need to be watching the logger or disable cosmetic filtering to notice it).

Replacing that CSS rule with an HTML filter would remove the banners altogether without the need for an extra rule to block the images directly (on Firefox 57+ and then Chromium when this is supported), and already make it future-proof for whatever URL they decide to start using for the images, as long as they keep the same CSS class, of course.

@ameshkov You may be interested in what I'm saying in this thread.

@gorhill Note that implementing what I suggested (adding equivalent ###/##. rules automatically to ##^#/##^.) will still hide future elements (re-)added dynamically with the same class, just as expected when plain cosmetic filters are used, so this isn't just about making it backwards-compatible, but also making ^. more useful for cases where new elements with the same class are added.

gorhill commented 6 years ago

Thinking more about it, this can't work, the semantic is too different. You can find cases for which this works, but then the question will become what for cases for which the conversion causes issues.

okiehsch commented 6 years ago

You can just disable the inline-script that pushes the ads at moviechat.org, in which case it does not matter if they change the path again. For example moviechat.org##script:inject(abort-current-inline-script.js, $, adblock) should work.

anewuser commented 6 years ago

@okiehsch Apparently they've changed their code again. It had simple static image tags with custom banners inside .adc before, not Amazon banners inserted by a script. That's why I used it as a case for HTML filtering. Anyway, this was just an example of what I had I mind.

I've converted all of my personal cosmetic filters to HTML filters after updating uBlock Origin. This is a feature I missed from the old Opera, which blocked the download of images and other resources hidden by userCSS.

Well, let's hope Google doesn't take long to support HTML filtering.

gorhill commented 6 years ago

We can still use HTML filtering for cases where it's worth it (possibly on some Polish sites from what I've seen) -- even if we have to create another extra filter for Chromium (or not and suggest users to move to Firefox when there is no solution for Chromium). Ideally Chromium will implement the filterResponseData API (which would render uBO-Extra irrelevant) and we won't have to worry about this.