[webkit-reviews] review denied: [Bug 207290] [Web Animations] Add support for `pseudoElement` on `KeyframeEffect` and `KeyframeEffectOptions` : [Attachment 396097] Patch

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Apr 14 04:28:11 PDT 2020


Antti Koivisto <koivisto at iki.fi> has denied Antoine Quint <graouts at apple.com>'s
request for review:
Bug 207290: [Web Animations] Add support for `pseudoElement` on
`KeyframeEffect` and `KeyframeEffectOptions`
https://bugs.webkit.org/show_bug.cgi?id=207290

Attachment 396097: Patch

https://bugs.webkit.org/attachment.cgi?id=396097&action=review




--- Comment #9 from Antti Koivisto <koivisto at iki.fi> ---
Comment on attachment 396097
  --> https://bugs.webkit.org/attachment.cgi?id=396097
Patch

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

I think this patch is heading to a wrong direction with expanded use of
PseudoElement. I feel the animation code should be refactored to minimise its
use first. Nevertheless I'd r+ this with some cleanups since it is not very
large and clearly adds useful functionality.

> Source/WebCore/animation/KeyframeEffect.cpp:1104
> +static Element* ensurePseudoElement(Element* host, PseudoId pseudoId)
> +{
> +    ASSERT(host);
> +
> +    if (pseudoId == PseudoId::Before) {
> +	   if (auto* beforePseudoElement = host->beforePseudoElement())
> +	       return beforePseudoElement;
> +	   auto newBeforePseudoElement = PseudoElement::create(*host,
pseudoId);
> +	   host->setBeforePseudoElement(WTFMove(newBeforePseudoElement));
> +	   return host->beforePseudoElement();
> +    }
> +
> +    if (pseudoId == PseudoId::After) {
> +	   if (auto* afterPseudoElement = host->afterPseudoElement())
> +	       return afterPseudoElement;
> +	   auto newAfterPseudoElement = PseudoElement::create(*host, pseudoId);
> +	   host->setAfterPseudoElement(WTFMove(newAfterPseudoElement));
> +	   return host->afterPseudoElement();
> +    }
> +
> +    ASSERT_NOT_REACHED();
> +    return nullptr;

This is the 3rd instance of this code. At least it should go to Element where
it can be shared.

> Source/WebCore/animation/KeyframeEffect.cpp:1113
> +void KeyframeEffect::setBindingsTarget(RefPtr<Element>&& target)
> +{
> +    if (m_pseudoId && target)
> +	   setTarget(ensurePseudoElement(target.get(), *m_pseudoId));
> +    else
> +	   setTarget(WTFMove(target));
> +}

So nasty.

It seems to me that the right factoring is to save the target Element (not
PseudoElement) and m_pseudoId, then have a helper that returns either Element
or PseudoElement based on those. Current m_target users would switch to that.

> Source/WebCore/animation/KeyframeEffect.cpp:1161
> +    // If the provided value is not null or a syntactically valid the user
agent must throw a DOMException with error name TypeError and leave the
> +    // target pseudo-selector of this animation effect unchanged.

The code below throws on syntactically valid but unhandled selectors. That's
not what this text says.

> Source/WebCore/animation/KeyframeEffect.cpp:1172
> +    if (!pseudoElement)
> +	   m_pseudoId = WTF::nullopt;
> +    else if (pseudoElement == "::before" || pseudoElement == ":before")
> +	   m_pseudoId = PseudoId::Before;
> +    else if (pseudoElement == "::after" || pseudoElement == ":after")
> +	   m_pseudoId = PseudoId::After;
> +    else
> +	   return Exception { TypeError };

Why is this done manually instead of using the parsing facilities?

> Source/WebCore/animation/KeyframeEffect.cpp:1182
> +    if (!m_pseudoId) {
> +	   if (is<PseudoElement>(m_target.get()))
> +	       setTarget(downcast<PseudoElement>(*m_target).hostElement());
> +    } else {
> +	   if (is<PseudoElement>(m_target.get()))
> +	      
setTarget(ensurePseudoElement(downcast<PseudoElement>(*m_target).hostElement(),
*m_pseudoId));
> +	   else if (auto* target = m_target.get())
> +	       setTarget(ensurePseudoElement(target, *m_pseudoId));
> +    }

:(

> Source/WebCore/animation/KeyframeEffect.cpp:1759
> +bool KeyframeEffect::requiresPseudoElement() const
> +{
> +    return m_blendingKeyframesSource ==
BlendingKeyframesSource::WebAnimation && is<PseudoElement>(m_target.get());
> +}

Only one of the m_pseudoId and is<PseudoElement>(m_target) should be
authorative and you should stick to that (m_pseudoId in practice as we want to
get rid of PseudoElement).


More information about the webkit-reviews mailing list