Bug 218792

Summary: Support animations on more pseudo-elements
Product: WebKit Reporter: Antoine Quint <graouts>
Component: AnimationsAssignee: Antoine Quint <graouts>
Status: RESOLVED FIXED    
Severity: Normal CC: cdumez, changseok, dino, esprehn+autocc, ews-watchlist, glenn, graouts, gyuyoung.kim, kangil.han, koivisto, kondapallykalyan, macpherson, menard, pdr, webkit-bug-importer
Priority: P2 Keywords: InRadar, WebExposed
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=220652
Bug Depends on: 218894    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
koivisto: review+, ews-feeder: commit-queue-
Patch
none
Patch none

Description Antoine Quint 2020-11-11 01:17:28 PST
Support animations on more pseudo-elements
Comment 1 Radar WebKit Bug Importer 2020-11-11 01:18:33 PST
<rdar://problem/71274485>
Comment 2 Antoine Quint 2020-11-11 01:43:40 PST
Created attachment 413798 [details]
Patch
Comment 3 Antoine Quint 2020-11-11 01:43:45 PST
<rdar://problem/71274485>
Comment 4 Antoine Quint 2020-11-11 03:03:28 PST
Created attachment 413804 [details]
Patch
Comment 5 Antoine Quint 2020-11-12 09:25:52 PST
Created attachment 413942 [details]
Patch
Comment 6 Antoine Quint 2020-11-12 09:29:09 PST
To whomever ends up reviewing this: this patch makes http://wpt.live/css/css-pseudo/marker-font-variant-numeric-default.html regress since relying on ::before::marker and ::after::marker in the user-agent stylesheet seems to no longer apply `font-variant-numeric: tabular-nums` whereas it would when that property was hard-coded in RenderListItem. However, not making that change would cause some other WPT failures with `font-variant-numeric` not being able to be set to `reset` for `::marker` since it would not have a user-agent-defined value to revert to and it would use `normal`.

I think we mark this failure as expected and file a dedicated bug to deal with ::before::marker and ::after:marker.
Comment 7 Antoine Quint 2020-11-12 23:55:30 PST
Created attachment 414007 [details]
Patch
Comment 8 Antoine Quint 2020-11-13 07:13:43 PST
Created attachment 414041 [details]
Patch
Comment 9 Antti Koivisto 2020-11-13 07:49:55 PST
Comment on attachment 414041 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=414041&action=review

> Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:302
> -void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdate& update)
> +void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdates* updates)
>  {
> +    ASSERT(updates);

Why is this now taking a pointer if it can't be null? Please switch back to a reference.

> Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:110
> +void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current, const Style::ElementUpdates* updates, PseudoId pseudoId)

Why is this taking a ElementUpdates pointer? The call sites null test so it should be a reference.

> Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:117
> +    auto* update = [updates, pseudoId]() -> const Style::ElementUpdate* {

could just use [&]

> Source/WebCore/style/StyleTreeResolver.cpp:251
> -    auto beforeUpdate = resolvePseudoStyle(element, update, PseudoId::Before);
> -    auto afterUpdate = resolvePseudoStyle(element, update, PseudoId::After);
> +    PseudoIdToElementUpdateMap pseudoUpdates;
> +    for (PseudoId pseudoId = PseudoId::FirstPublicPseudoId; pseudoId < PseudoId::FirstInternalPseudoId; pseudoId = static_cast<PseudoId>(static_cast<unsigned>(pseudoId) + 1)) {
> +        if (auto elementUpdate = resolvePseudoStyle(element, update, pseudoId))
> +            pseudoUpdates.set(pseudoId, WTFMove(*elementUpdate));
> +    }

At least::marker (anything else?) matches every element (since it is in the UA sheet) but only those with display:list-item care about it. It seems wasteful (and potential a perf regression) to resolve it eagerly in all cases. Maybe there should be a filter here that tests if a given pseudo element is relevant before resolving?

> Source/WebCore/style/StyleTreeResolver.cpp:269
> -        return { };
> +        return WTF::nullopt;

{ } would have still worked in these
Comment 10 Antoine Quint 2020-11-13 08:25:38 PST
(In reply to Antti Koivisto from comment #9)
> Comment on attachment 414041 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=414041&action=review
> 
> > Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:302
> > -void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdate& update)
> > +void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdates* updates)
> >  {
> > +    ASSERT(updates);
> 
> Why is this now taking a pointer if it can't be null? Please switch back to
> a reference.

Will fix in new patch.

> > Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:110
> > +void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current, const Style::ElementUpdates* updates, PseudoId pseudoId)
> 
> Why is this taking a ElementUpdates pointer? The call sites null test so it
> should be a reference.

Will fix in new patch.

> > Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:117
> > +    auto* update = [updates, pseudoId]() -> const Style::ElementUpdate* {
> 
> could just use [&]

Indeed, will fix in new patch.

> > Source/WebCore/style/StyleTreeResolver.cpp:251
> > -    auto beforeUpdate = resolvePseudoStyle(element, update, PseudoId::Before);
> > -    auto afterUpdate = resolvePseudoStyle(element, update, PseudoId::After);
> > +    PseudoIdToElementUpdateMap pseudoUpdates;
> > +    for (PseudoId pseudoId = PseudoId::FirstPublicPseudoId; pseudoId < PseudoId::FirstInternalPseudoId; pseudoId = static_cast<PseudoId>(static_cast<unsigned>(pseudoId) + 1)) {
> > +        if (auto elementUpdate = resolvePseudoStyle(element, update, pseudoId))
> > +            pseudoUpdates.set(pseudoId, WTFMove(*elementUpdate));
> > +    }
> 
> At least::marker (anything else?) matches every element (since it is in the
> UA sheet) but only those with display:list-item care about it. It seems
> wasteful (and potential a perf regression) to resolve it eagerly in all
> cases. Maybe there should be a filter here that tests if a given pseudo
> element is relevant before resolving?

resolvePseudoStyle() bails if !elementUpdate.style->hasPseudoStyle(pseudoId) but we can move this up to the call site.

> > Source/WebCore/style/StyleTreeResolver.cpp:269
> > -        return { };
> > +        return WTF::nullopt;
> 
> { } would have still worked in these

Oh, cool! Will move back to { } to make a smaller diff.
Comment 11 Antoine Quint 2020-11-13 08:25:59 PST
Created attachment 414046 [details]
Patch
Comment 12 Antti Koivisto 2020-11-13 08:29:06 PST
> resolvePseudoStyle() bails if !elementUpdate.style->hasPseudoStyle(pseudoId)
> but we can move this up to the call site.

That won't help since hasPseudoStyle(marker) is true for every element.
Comment 13 Antoine Quint 2020-11-13 08:48:01 PST
Created attachment 414049 [details]
Patch
Comment 14 Antoine Quint 2020-11-13 08:49:03 PST
(In reply to Antti Koivisto from comment #12)
> > resolvePseudoStyle() bails if !elementUpdate.style->hasPseudoStyle(pseudoId)
> > but we can move this up to the call site.
> 
> That won't help since hasPseudoStyle(marker) is true for every element.

Right! I added a check for `::marker` to check that `display: list-item` is set for the element.
Comment 15 Antti Koivisto 2020-11-13 09:04:27 PST
Comment on attachment 414049 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=414049&action=review

> Source/WebCore/style/StyleTreeResolver.cpp:273
> +    if (pseudoId == PseudoId::Marker && elementUpdate.style->display() != DisplayType::ListItem)
> +        return { };
>      if (elementUpdate.style->display() == DisplayType::None)
>          return { };
>      if (!elementUpdate.style->hasPseudoStyle(pseudoId))

this stuff could be factored into a function (shouldResolvePseudoElementStyle or similar).
Comment 16 Antti Koivisto 2020-11-13 09:15:19 PST
Comment on attachment 414049 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=414049&action=review

> Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:117
> +    auto* update = [&]() -> const Style::ElementUpdate* {

This can probably be just [&] {
Comment 17 Antoine Quint 2020-11-13 11:23:21 PST
(In reply to Antti Koivisto from comment #16)
> Comment on attachment 414049 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=414049&action=review
> 
> > Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:117
> > +    auto* update = [&]() -> const Style::ElementUpdate* {
> 
> This can probably be just [&] {

The compiler wants an explicit return type.
Comment 18 Antoine Quint 2020-11-13 11:25:11 PST
Created attachment 414070 [details]
Patch
Comment 19 Antoine Quint 2020-11-13 12:49:57 PST
Created attachment 414085 [details]
Patch
Comment 20 Antoine Quint 2020-11-14 01:01:33 PST
Committed r269813: <https://trac.webkit.org/changeset/269813>
Comment 21 Antoine Quint 2021-01-15 02:00:30 PST
This appears to have caused bug 220652.