Bug 239868

Summary: [:has() pseudo-class] is flaky when passing a selector that contains :empty
Product: WebKit Reporter: Bruno Silva <brsil>
Component: CSSAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: aarfing, koivisto, ntim, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 15   
Hardware: All   
OS: All   
Bug Depends on:    
Bug Blocks: 227702    
Attachments:
Description Flags
Test page showing the issue where :has() is not triggering a update none

Description Bruno Silva 2022-04-28 13:30:09 PDT
Created attachment 458545 [details]
Test page showing the issue where :has() is not triggering a update

While using the pseudo class selector :has() in combination with the ::after pseudo-element and passing a selector to the :has that contains the :empty pseudo class I get a flaky behavior where making a change that would make the selector passed to the :has() be invalid does not actually invalidate the selector that has the :has() resulting in a flaky behavior.

To see the behavior in action on the attached test page do the following steps:
1. Click on the add child button
   1.1. You should see a child that is not empty and has a random number or,
   1.2. A child that has no content and the text "::after text" is displayed from the ::after element on the parent
2. If you got a empty child now click on the add text button

Expected:
The child is now not empty therefore the selector ".parent:has(.child:only-child:empty)::after" is invalid and the "::after text" should disappear from the parent element

Currently:
The "::after text" is still present on the parent and has no selector matching it
Comment 1 Radar WebKit Bug Importer 2022-04-28 15:43:56 PDT
<rdar://problem/92492066>
Comment 2 Antti Koivisto 2022-05-30 05:12:57 PDT
Seems more of a layout update issue than style, resizing the page makes the bug go away.
Comment 3 aarfing 2023-01-19 05:05:01 PST
I see the same thing.

Trying to hide a wrapper-div if no ad is injected in it. This doesn't work, although the correct :has() style is set on the wrapper, if you look in the inspector, the style isn't applied before a repaint is forced.
Comment 4 Antti Koivisto 2023-01-19 06:31:57 PST
Actually I think we lack :has() aware invalidation for :empty.
Comment 5 aarfing 2023-01-19 23:22:28 PST
(In reply to Antti Koivisto from comment #4)
> Actually I think we lack :has() aware invalidation for :empty.

I did some further tests, and I think you're right.