Accelerated animations on ::backdrop shouldn't affect <dialog> (backdrop-animate-002.html fails)
https://bugs.webkit.org/show_bug.cgi?id=230008
<rdar://problem/82975766>

Reviewed by Simon Fraser and Tim Nguyen.

Source/WebCore:

We did not know how to access the ::backdrop renderer when running accelerated animations. To do so we now
implement full support to access the renderer for known pseudo-elements on Styleable with a new renderer()
method, including ::backdrop. We also make Styleable::fromRenderer() aware of ::backdrop such that the various
call sites for this function that deal with accelerated transform animations access the right element.

* animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::renderer const):
* style/Styleable.cpp:
(WebCore::Styleable::fromRenderer):
(WebCore::Styleable::renderer const):
* style/Styleable.h:
(WebCore::Styleable::fromRenderer): Deleted.

LayoutTests:

* TestExpectations: Mark the previously failing test as passing.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@284313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c7e9609..f768bae 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,5 +1,15 @@
 2021-10-15  Antoine Quint  <graouts@webkit.org>
 
+        Accelerated animations on ::backdrop shouldn't affect <dialog> (backdrop-animate-002.html fails)
+        https://bugs.webkit.org/show_bug.cgi?id=230008
+        <rdar://problem/82975766>
+
+        Reviewed by Simon Fraser and Tim Nguyen.
+
+        * TestExpectations: Mark the previously failing test as passing.
+
+2021-10-15  Antoine Quint  <graouts@webkit.org>
+
         CSS Animations creation and sorting is incorrect and may lead to crash
         https://bugs.webkit.org/show_bug.cgi?id=231812
         <rdar://problem/82980774>
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index 9cf3823..9c6544b 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -5127,8 +5127,6 @@
 
 webkit.org/b/230237 imported/w3c/web-platform-tests/css/cssom-view/scrollIntoView-inline-image.html [ Failure ]
 
-webkit.org/b/230008 imported/w3c/web-platform-tests/css/css-pseudo/backdrop-animate-002.html [ ImageOnlyFailure ]
-
 webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/active-selection-012.html [ ImageOnlyFailure ]
 webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/active-selection-014.html [ ImageOnlyFailure ]
 webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/active-selection-018.html [ ImageOnlyFailure ]
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 33889d9..47e464b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,26 @@
 2021-10-15  Antoine Quint  <graouts@webkit.org>
 
+        Accelerated animations on ::backdrop shouldn't affect <dialog> (backdrop-animate-002.html fails)
+        https://bugs.webkit.org/show_bug.cgi?id=230008
+        <rdar://problem/82975766>
+
+        Reviewed by Simon Fraser and Tim Nguyen.
+
+        We did not know how to access the ::backdrop renderer when running accelerated animations. To do so we now
+        implement full support to access the renderer for known pseudo-elements on Styleable with a new renderer()
+        method, including ::backdrop. We also make Styleable::fromRenderer() aware of ::backdrop such that the various
+        call sites for this function that deal with accelerated transform animations access the right element.
+
+        * animation/KeyframeEffect.cpp:
+        (WebCore::KeyframeEffect::renderer const):
+        * style/Styleable.cpp:
+        (WebCore::Styleable::fromRenderer):
+        (WebCore::Styleable::renderer const):
+        * style/Styleable.h:
+        (WebCore::Styleable::fromRenderer): Deleted.
+
+2021-10-15  Antoine Quint  <graouts@webkit.org>
+
         CSS Animations creation and sorting is incorrect and may lead to crash
         https://bugs.webkit.org/show_bug.cgi?id=231812
         <rdar://problem/82980774>
diff --git a/Source/WebCore/animation/KeyframeEffect.cpp b/Source/WebCore/animation/KeyframeEffect.cpp
index af2503d..ce68c71 100644
--- a/Source/WebCore/animation/KeyframeEffect.cpp
+++ b/Source/WebCore/animation/KeyframeEffect.cpp
@@ -1873,7 +1873,9 @@
 
 RenderElement* KeyframeEffect::renderer() const
 {
-    return targetElementOrPseudoElement() ? targetElementOrPseudoElement()->renderer() : nullptr;
+    if (auto target = targetStyleable())
+        return target->renderer();
+    return nullptr;
 }
 
 const RenderStyle& KeyframeEffect::currentStyle() const
diff --git a/Source/WebCore/style/Styleable.cpp b/Source/WebCore/style/Styleable.cpp
index 3048c65..cfb076f 100644
--- a/Source/WebCore/style/Styleable.cpp
+++ b/Source/WebCore/style/Styleable.cpp
@@ -39,6 +39,9 @@
 #include "Element.h"
 #include "KeyframeEffect.h"
 #include "KeyframeEffectStack.h"
+#include "RenderElement.h"
+#include "RenderListItem.h"
+#include "RenderListMarker.h"
 #include "RenderStyle.h"
 #include "StylePropertyShorthand.h"
 #include "StyleResolver.h"
@@ -48,6 +51,64 @@
 
 namespace WebCore {
 
+const std::optional<const Styleable> Styleable::fromRenderer(const RenderElement& renderer)
+{
+    switch (renderer.style().styleType()) {
+    case PseudoId::Backdrop:
+        for (auto& topLayerElement : renderer.document().topLayerElements()) {
+            if (topLayerElement->renderer() && topLayerElement->renderer()->backdropRenderer() == &renderer)
+                return Styleable(topLayerElement.get(), PseudoId::Backdrop);
+        }
+        break;
+    case PseudoId::Marker:
+        if (auto* parent = renderer.parent()) {
+            ASSERT(parent->element());
+            ASSERT(is<RenderListItem>(parent));
+            ASSERT(downcast<RenderListItem>(*parent).markerRenderer() == &renderer);
+            return Styleable(*parent->element(), PseudoId::Marker);
+        }
+        break;
+    case PseudoId::After:
+    case PseudoId::Before:
+    case PseudoId::None:
+        if (auto* element = renderer.element())
+            return fromElement(*element);
+        break;
+    default:
+        return std::nullopt;
+    }
+
+    return std::nullopt;
+}
+
+RenderElement* Styleable::renderer() const
+{
+    switch (pseudoId) {
+    case PseudoId::After:
+        if (auto* afterPseudoElement = element.afterPseudoElement())
+            return afterPseudoElement->renderer();
+        break;
+    case PseudoId::Backdrop:
+        if (auto* hostRenderer = element.renderer())
+            return hostRenderer->backdropRenderer().get();
+        break;
+    case PseudoId::Before:
+        if (auto* beforePseudoElement = element.beforePseudoElement())
+            return beforePseudoElement->renderer();
+        break;
+    case PseudoId::Marker:
+        if (is<RenderListItem>(element.renderer()))
+            return downcast<RenderListItem>(*element.renderer()).markerRenderer();
+        break;
+    case PseudoId::None:
+        return element.renderer();
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    return nullptr;
+}
+
 void Styleable::animationWasAdded(WebAnimation& animation) const
 {
     ensureAnimations().add(&animation);
diff --git a/Source/WebCore/style/Styleable.h b/Source/WebCore/style/Styleable.h
index c0d4756..23c8afa 100644
--- a/Source/WebCore/style/Styleable.h
+++ b/Source/WebCore/style/Styleable.h
@@ -28,13 +28,13 @@
 #include "Element.h"
 #include "KeyframeEffectStack.h"
 #include "PseudoElement.h"
-#include "RenderElement.h"
 #include "RenderStyleConstants.h"
 #include "WebAnimationTypes.h"
 
 namespace WebCore {
 
 class KeyframeEffectStack;
+class RenderElement;
 class RenderStyle;
 class WebAnimation;
 
@@ -56,12 +56,7 @@
         return Styleable(element, element.pseudoId());
     }
 
-    static const std::optional<const Styleable> fromRenderer(const RenderElement& renderer)
-    {
-        if (auto* element = renderer.element())
-            return fromElement(*element);
-        return std::nullopt;
-    }
+    static const std::optional<const Styleable> fromRenderer(const RenderElement&);
 
     bool operator==(const Styleable& other) const
     {
@@ -73,6 +68,8 @@
         return !(*this == other);
     }
 
+    RenderElement* renderer() const;
+
     KeyframeEffectStack* keyframeEffectStack() const
     {
         return element.keyframeEffectStack(pseudoId);