NanoAdblocker / NanoCore

An adblocker
GNU General Public License v3.0
457 stars 22 forks source link

Make ":after" and ":before" selectable in the element picker #233

Open DandelionSprout opened 5 years ago

DandelionSprout commented 5 years ago

Describe the issue (Required)

When writing an entry that includes :before or :after into the element picker's text box, the element picker is unable to recognise the element and will refuse to make the Create button clickable.

Screenshots (Required)

image

Screenshot of console (Required, press F12 to open the console)

image

Reproduction Steps (Optional if trivial)

0) Ensure that Dandelion Sprouts nordiske filtre is turned off. 1) Visit a website that has at least one element with a ::after or ::before CSS subelement. For this walkthrough, I'll use https://www.aftenbladet.no/lokalt/i/zLBMXb/Var-obs-nar-du-parkerer-pa-disse-stedene as the example. 2) Attempt to write a filter that involves either :after or :before (with one colon, not two). Example for the example page: ##.overlay-wrap:before 3) See that the element picker thinks that it's an incorrect syntax, and will either show 0 results or (as in this case) an E error sign. 4) Quit the element picker, and paste aftenbladet.no##.overlay-wrap:before into My Filters. 5) Reload the Aftenbladet page. 6) See that a string of text suddenly isn't blurred anymore, and that it's in clear-as-day black-on-white, which means that the entry's syntax is in fact correct and that the element picker should be updated to become aware of this.

Anything else you believe to be useful (Optional)

As for my use, :after and :before entries are particularly important when writing entries for Norwegian newssites, most of whom uses a subscription system, as well as article previews that are a few lines long and which gradually become more blurry by the end of the preview.

I would be surprised if this issue doesn't apply to uBlock Origin as well, but as I am chiefly using Nano Adblocker on my main browser, I decided to try to report it here first.

Environment (Required)

Your filter lists (Required)

Nano Defender Integration
Nano filters
Nano filters - Whitelist
uBlock filters - Badware Risks
uBlock filters - Unbreak
Adblock Warning Removal List
Adguard Base Filters
Adguard Mobile Filters
EasyList
Malvertising filter list by Disconnect
Malware Domain List
Malware domains
Spam404
Fanboy's Social Blocking List
Dandelion Sprouts nordiske filtre (Not used during the example procedure above)
Shalla Malware
Confirmed Phishing Threats (by MrThreat)
Streaming Ads (by FadeMind)
AbuseCH Ransomware Tracker RW URLBL
Hosts-File PUP
Hosts-File EMD
Phishing Hosts (by Kurobeats)
Anti-FiM List
Anti-Futa List
MeWe Pink Theme
Dandelion Sprout's Website Stretcher
I Hate Overpromoted Games
I don't care about cookies
YouTube: Pure Video Experience
YouTube: Even More Pure Video Experience
Wikia: Pure Browsing Experience
Twitch: Pure Viewing Experience
Browse Websites Without Logging In
Anti-IMDB List
I Don't Want to Download Your Browser
Anti-'Abuse porn' List
Anti-'Battle Royale' List
Anti-'Notification pre-prompt banners' List
Stop AutoPlay on YouTube
Anti-Elsagate List

Your custom filters (Required if you have any)

https://raw.githubusercontent.com/DandelionSprout/adfilt/master/a.txt

gwarser commented 5 years ago

It's because querying for pseudo elements returns no elements. This will require special handling / injecting styles blindly.

jspenguin2017 commented 5 years ago

You really should use DevTools if you need to create a filter that's not trivial.

The problem with implementing pseudo elements selection in the Element Picker is that I don't see a way to calculate the bounding rectangle of the element. I know DevTools is able to do that, but I think they are using internal APIs.

image

jspenguin2017 commented 5 years ago

DevTools can totally select pseudo elements. Can someone investigate what black magic they are using?

gwarser commented 5 years ago

Your example does not work in Firefox, but this can be used https://makandracards.com/makandra/58174-how-to-access-before-after-pseudo-element-styles-with-javascript

style = window.getComputedStyle(real_element, '::before')
color = style.getPropertyValue('width')

Needs more magic for x/y

jspenguin2017 commented 5 years ago

It might be possible to guess the x and y values. I still want to see how DevTools did it though...

image

jspenguin2017 commented 5 years ago

Was this reported to upstream issues tracker before?

gwarser commented 5 years ago

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


https://github.com/gorhill/uBlock/issues/2825#issuecomment-318158409

The picker doesn't look at pseudo-class, and I don't want to change this, the cost would be beyond reasonable. In such case, using the browser inspector is the preferred solution.

jspenguin2017 commented 5 years ago

If by "cost" he means computation costs, then I disagree. You don't need to scan the pseudo elements of everything, only those that match the selector before :before or :after. It may cause some problem if the selector matches too many elements, but we can add a cap to how many pseudo elements to compute (99 maybe?). As for mouse cursor, the current implementation is able to highlight the real element when I hover the pseudo element, so it's up to 2 style computation at most.

However, implementing this is by no mean easy, and it'll cost a lot of time. Since I pretty much never use the element picker, I don't really feel like implementing this. Personally I just use DevTools, which can select pseudo elements without any hassle.

yourduskquibbles commented 5 years ago

As of uBlock Origin 1.18.17b11 I have found through random filter creation that the element picker will actually create and preview pseudo-element filters when you combine multiple class selections in the element picker filter box with at least one non pseudo-element and apply a :style() tag to the filter.

e.g. combination filter ##.mbr-navbar__brand-link::after, .mbr-navbar__brand-img:style(height: 74px !important;) will set the height to 74px and allow for preview in the element filter creation box for elements ##.mbr-navbar__brand-link::after & ##.mbr-navbar__brand-img

From what I have tested for, this seems to work when there is a combined filter for multiple classes separated by commas on the same line with a :style() tag also applied.

Test Link https://www.autohotkey.com/

Use element picker and add the following filter to filter line ##.mbr-navbar__brand-link::after, .mbr-navbar__brand-img:style(height: 74px !important;)

Pseudo-element filter is able to be created from Element Picker and you also get the benefit of previewing the filter before adding to 'My Filters'.

Additionally, the order of when the pseudo-element is used in the element picker filter box also doesn't seem to matter so ##.mbr-navbar__brand-img, .mbr-navbar__brand-link::after:style(height: 74px !important;) and ##.mbr-navbar__brand-link::after, .mbr-navbar__brand-img:style(height: 74px !important;) both seem to work.

Posting this here as an FYI since https://github.com/gorhill/uBlock/issues/2515 & https://github.com/gorhill/uBlock/issues/2825 are closed for commenting, maybe someone will find this post via those links and find this helpful.