Title: [291667] branches/safari-613-branch
Revision
291667
Author
alanc...@apple.com
Date
2022-03-22 10:56:48 -0700 (Tue, 22 Mar 2022)

Log Message

Cherry-pick r291282. rdar://problem/88857731

    Dialog element only animates once
    https://bugs.webkit.org/show_bug.cgi?id=236274

    Reviewed by Dean Jackson, Tim Nguyen and Antti Koivisto.

    LayoutTests/imported/w3c:

    Import relevant WPT tests that had already been upstreamed in a previous, reverted
    version of this patch.

    * web-platform-tests/css/css-animations/dialog-animation-expected.txt: Added.
    * web-platform-tests/css/css-animations/dialog-animation.html: Added.
    * web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt: Added.
    * web-platform-tests/css/css-animations/dialog-backdrop-animation.html: Added.
    * web-platform-tests/css/css-animations/support/testcommon.js:
    (addElement):
    (addDiv):

    Source/WebCore:

    Two issues related to CSS Animation surfaced in this bug which animates both <dialog>
    and its ::backdrop as the dialog is open and eventually re-opened.

    The first issue was that we didn't clear all CSS Animations state when a <dialog> was
    closed and its style was set to `display: none`. We now call setAnimationsCreatedByMarkup
    to correctly clear such state both when we identify a Styleable is newly getting
    `display: none`. We do the same when cancelDeclarativeAnimations() is called, but also
    call setCSSAnimationList() on the associated effect stack since that wasn't done either.
    Now both functions do similar cleanup.

    This allows us to remove removeCSSAnimationCreatedByMarkup() which did a fair bit of work
    to clear CSS Animation state per-animation when we only ever used that function for
    _all_ animations.

    The second issue was that we never called cancelDeclarativeAnimations() for ::backdrop.
    We now do that inside of Element::removeFromTopLayer() at a point where the code in
    Styleable::fromRenderer() will still work as the element will still be contained in
    Document::topLayerElements().

    Tests: imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html
           imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html

    * dom/Element.cpp:
    (WebCore::Element::removeFromTopLayer):
    * style/Styleable.cpp:
    (WebCore::Styleable::cancelDeclarativeAnimations const):
    (WebCore::Styleable::updateCSSAnimations const):
    (WebCore::removeCSSAnimationCreatedByMarkup): Deleted.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291282 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-613-branch/LayoutTests/imported/w3c/ChangeLog (291666 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/ChangeLog	2022-03-22 17:56:43 UTC (rev 291666)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/ChangeLog	2022-03-22 17:56:48 UTC (rev 291667)
@@ -1,3 +1,77 @@
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r291282. rdar://problem/88857731
+
+    Dialog element only animates once
+    https://bugs.webkit.org/show_bug.cgi?id=236274
+    
+    Reviewed by Dean Jackson, Tim Nguyen and Antti Koivisto.
+    
+    LayoutTests/imported/w3c:
+    
+    Import relevant WPT tests that had already been upstreamed in a previous, reverted
+    version of this patch.
+    
+    * web-platform-tests/css/css-animations/dialog-animation-expected.txt: Added.
+    * web-platform-tests/css/css-animations/dialog-animation.html: Added.
+    * web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt: Added.
+    * web-platform-tests/css/css-animations/dialog-backdrop-animation.html: Added.
+    * web-platform-tests/css/css-animations/support/testcommon.js:
+    (addElement):
+    (addDiv):
+    
+    Source/WebCore:
+    
+    Two issues related to CSS Animation surfaced in this bug which animates both <dialog>
+    and its ::backdrop as the dialog is open and eventually re-opened.
+    
+    The first issue was that we didn't clear all CSS Animations state when a <dialog> was
+    closed and its style was set to `display: none`. We now call setAnimationsCreatedByMarkup
+    to correctly clear such state both when we identify a Styleable is newly getting
+    `display: none`. We do the same when cancelDeclarativeAnimations() is called, but also
+    call setCSSAnimationList() on the associated effect stack since that wasn't done either.
+    Now both functions do similar cleanup.
+    
+    This allows us to remove removeCSSAnimationCreatedByMarkup() which did a fair bit of work
+    to clear CSS Animation state per-animation when we only ever used that function for
+    _all_ animations.
+    
+    The second issue was that we never called cancelDeclarativeAnimations() for ::backdrop.
+    We now do that inside of Element::removeFromTopLayer() at a point where the code in
+    Styleable::fromRenderer() will still work as the element will still be contained in
+    Document::topLayerElements().
+    
+    Tests: imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html
+           imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html
+    
+    * dom/Element.cpp:
+    (WebCore::Element::removeFromTopLayer):
+    * style/Styleable.cpp:
+    (WebCore::Styleable::cancelDeclarativeAnimations const):
+    (WebCore::Styleable::updateCSSAnimations const):
+    (WebCore::removeCSSAnimationCreatedByMarkup): Deleted.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-15  Antoine Quint  <grao...@webkit.org>
+
+            Dialog element only animates once
+            https://bugs.webkit.org/show_bug.cgi?id=236274
+
+            Reviewed by Dean Jackson, Tim Nguyen and Antti Koivisto.
+
+            Import relevant WPT tests that had already been upstreamed in a previous, reverted
+            version of this patch.
+
+            * web-platform-tests/css/css-animations/dialog-animation-expected.txt: Added.
+            * web-platform-tests/css/css-animations/dialog-animation.html: Added.
+            * web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt: Added.
+            * web-platform-tests/css/css-animations/dialog-backdrop-animation.html: Added.
+            * web-platform-tests/css/css-animations/support/testcommon.js:
+            (addElement):
+            (addDiv):
+
 2022-03-09  Russell Epstein  <repst...@apple.com>
 
         Cherry-pick r290556. rdar://problem/89525864

Added: branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation-expected.txt (0 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation-expected.txt	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation-expected.txt	2022-03-22 17:56:48 UTC (rev 291667)
@@ -0,0 +1,3 @@
+
+PASS CSS Animations tied to <dialog open> are canceled and restarted as the dialog is hidden and shown
+

Added: branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html (0 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html	2022-03-22 17:56:48 UTC (rev 291667)
@@ -0,0 +1,44 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSS Animations on a &lt;dialog></title>
+<link rel="help" href=""
+<script src=""
+<script src=""
+<script src=""
+<style>
+
+dialog[open] {
+    animation: dialog-open-animation 1ms;
+}
+
+@keyframes dialog-open-animation {
+    from { opacity: 0 }
+}
+
+</style>
+<div id="log"></div>
+<script>
+
+"use strict";
+
+promise_test(async t => {
+  const dialog = addElement(t, "dialog");
+
+  // Open the dialog a first time, this should trigger a CSS Animation.
+  dialog.open = true;
+  const animations = dialog.getAnimations();
+  assert_equals(animations.length, 1, "As the <dialog> is shown intially an animation is started");
+
+  await animations[0].finished;
+
+  await waitForNextFrame();
+
+  dialog.open = false;
+  assert_equals(dialog.getAnimations().length, 0, "As the <dialog> is closed the animation is removed");
+
+  await waitForNextFrame();
+
+  dialog.open = true;
+  assert_equals(dialog.getAnimations().length, 1, "As the <dialog> is shown again an animation is started again");
+}, "CSS Animations tied to <dialog open> are canceled and restarted as the dialog is hidden and shown");
+</script>

Added: branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt (0 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt	2022-03-22 17:56:48 UTC (rev 291667)
@@ -0,0 +1,3 @@
+
+PASS CSS Animations on a <dialog> ::backdrop are canceled and restarted as the dialog is hidden and shown
+

Added: branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html (0 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html	2022-03-22 17:56:48 UTC (rev 291667)
@@ -0,0 +1,44 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSS Animations on a &lt;dialog> ::backdrop</title>
+<link rel="help" href=""
+<script src=""
+<script src=""
+<script src=""
+<style>
+
+dialog[open]::backdrop {
+    animation: dialog-backdrop-animation 1ms;
+}
+
+@keyframes dialog-backdrop-animation {
+    from { opacity: 0 }
+}
+
+</style>
+<div id="log"></div>
+<script>
+
+"use strict";
+
+promise_test(async t => {
+  const dialog = addElement(t, "dialog");
+
+  // Open the dialog a first time, this should trigger a CSS Animation.
+  dialog.showModal();
+  const animations = dialog.getAnimations({ subtree: true });
+  assert_equals(animations.length, 1, "As the <dialog> is shown intially an animation is started on its ::backdrop");
+
+  await animations[0].finished;
+
+  await waitForNextFrame();
+
+  dialog.close();
+  assert_equals(dialog.getAnimations({ subtree: true }).length, 0, "As the <dialog> is closed the animation is removed from its ::backdrop");
+
+  await waitForNextFrame();
+
+  dialog.showModal();
+  assert_equals(dialog.getAnimations({ subtree: true }).length, 1, "As the <dialog> is shown again an animation is started again on its ::backdrop");
+}, "CSS Animations on a <dialog> ::backdrop are canceled and restarted as the dialog is hidden and shown");
+</script>

Modified: branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/support/testcommon.js (291666 => 291667)


--- branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/support/testcommon.js	2022-03-22 17:56:43 UTC (rev 291666)
+++ branches/safari-613-branch/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/support/testcommon.js	2022-03-22 17:56:48 UTC (rev 291667)
@@ -87,34 +87,46 @@
 }
 
 /**
- * Appends a div to the document body.
+ * Appends an element to the document body.
  *
  * @param t  The testharness.js Test object. If provided, this will be used
  *           to register a cleanup callback to remove the div when the test
  *           finishes.
  *
+ * @param name  A string specifying the element name.
+ *
  * @param attrs  A dictionary object with attribute names and values to set on
  *               the div.
  */
-function addDiv(t, attrs) {
-  var div = document.createElement('div');
+function addElement(t, name, attrs) {
+  var element = document.createElement(name);
   if (attrs) {
     for (var attrName in attrs) {
-      div.setAttribute(attrName, attrs[attrName]);
+      element.setAttribute(attrName, attrs[attrName]);
     }
   }
-  document.body.appendChild(div);
+  document.body.appendChild(element);
   if (t && typeof t.add_cleanup === 'function') {
-    t.add_cleanup(function() {
-      if (div.parentNode) {
-        div.remove();
-      }
-    });
+      t.add_cleanup(() => element.remove());
   }
-  return div;
+  return element;
 }
 
 /**
+ * Appends a div to the document body.
+ *
+ * @param t  The testharness.js Test object. If provided, this will be used
+ *           to register a cleanup callback to remove the div when the test
+ *           finishes.
+ *
+ * @param attrs  A dictionary object with attribute names and values to set on
+ *               the div.
+ */
+function addDiv(t, attrs) {
+  return addElement(t, "div", attrs);
+}
+
+/**
  * Appends a style div to the document head.
  *
  * @param t  The testharness.js Test object. If provided, this will be used

Modified: branches/safari-613-branch/Source/WebCore/ChangeLog (291666 => 291667)


--- branches/safari-613-branch/Source/WebCore/ChangeLog	2022-03-22 17:56:43 UTC (rev 291666)
+++ branches/safari-613-branch/Source/WebCore/ChangeLog	2022-03-22 17:56:48 UTC (rev 291667)
@@ -1,5 +1,98 @@
 2022-03-21  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r291282. rdar://problem/88857731
+
+    Dialog element only animates once
+    https://bugs.webkit.org/show_bug.cgi?id=236274
+    
+    Reviewed by Dean Jackson, Tim Nguyen and Antti Koivisto.
+    
+    LayoutTests/imported/w3c:
+    
+    Import relevant WPT tests that had already been upstreamed in a previous, reverted
+    version of this patch.
+    
+    * web-platform-tests/css/css-animations/dialog-animation-expected.txt: Added.
+    * web-platform-tests/css/css-animations/dialog-animation.html: Added.
+    * web-platform-tests/css/css-animations/dialog-backdrop-animation-expected.txt: Added.
+    * web-platform-tests/css/css-animations/dialog-backdrop-animation.html: Added.
+    * web-platform-tests/css/css-animations/support/testcommon.js:
+    (addElement):
+    (addDiv):
+    
+    Source/WebCore:
+    
+    Two issues related to CSS Animation surfaced in this bug which animates both <dialog>
+    and its ::backdrop as the dialog is open and eventually re-opened.
+    
+    The first issue was that we didn't clear all CSS Animations state when a <dialog> was
+    closed and its style was set to `display: none`. We now call setAnimationsCreatedByMarkup
+    to correctly clear such state both when we identify a Styleable is newly getting
+    `display: none`. We do the same when cancelDeclarativeAnimations() is called, but also
+    call setCSSAnimationList() on the associated effect stack since that wasn't done either.
+    Now both functions do similar cleanup.
+    
+    This allows us to remove removeCSSAnimationCreatedByMarkup() which did a fair bit of work
+    to clear CSS Animation state per-animation when we only ever used that function for
+    _all_ animations.
+    
+    The second issue was that we never called cancelDeclarativeAnimations() for ::backdrop.
+    We now do that inside of Element::removeFromTopLayer() at a point where the code in
+    Styleable::fromRenderer() will still work as the element will still be contained in
+    Document::topLayerElements().
+    
+    Tests: imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html
+           imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html
+    
+    * dom/Element.cpp:
+    (WebCore::Element::removeFromTopLayer):
+    * style/Styleable.cpp:
+    (WebCore::Styleable::cancelDeclarativeAnimations const):
+    (WebCore::Styleable::updateCSSAnimations const):
+    (WebCore::removeCSSAnimationCreatedByMarkup): Deleted.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-15  Antoine Quint  <grao...@webkit.org>
+
+            Dialog element only animates once
+            https://bugs.webkit.org/show_bug.cgi?id=236274
+
+            Reviewed by Dean Jackson, Tim Nguyen and Antti Koivisto.
+
+            Two issues related to CSS Animation surfaced in this bug which animates both <dialog>
+            and its ::backdrop as the dialog is open and eventually re-opened.
+
+            The first issue was that we didn't clear all CSS Animations state when a <dialog> was
+            closed and its style was set to `display: none`. We now call setAnimationsCreatedByMarkup
+            to correctly clear such state both when we identify a Styleable is newly getting
+            `display: none`. We do the same when cancelDeclarativeAnimations() is called, but also
+            call setCSSAnimationList() on the associated effect stack since that wasn't done either.
+            Now both functions do similar cleanup.
+
+
+            This allows us to remove removeCSSAnimationCreatedByMarkup() which did a fair bit of work
+            to clear CSS Animation state per-animation when we only ever used that function for
+            _all_ animations.
+
+            The second issue was that we never called cancelDeclarativeAnimations() for ::backdrop.
+            We now do that inside of Element::removeFromTopLayer() at a point where the code in
+            Styleable::fromRenderer() will still work as the element will still be contained in
+            Document::topLayerElements().
+
+            Tests: imported/w3c/web-platform-tests/css/css-animations/dialog-animation.html
+                   imported/w3c/web-platform-tests/css/css-animations/dialog-backdrop-animation.html
+
+            * dom/Element.cpp:
+            (WebCore::Element::removeFromTopLayer):
+            * style/Styleable.cpp:
+            (WebCore::Styleable::cancelDeclarativeAnimations const):
+            (WebCore::Styleable::updateCSSAnimations const):
+            (WebCore::removeCSSAnimationCreatedByMarkup): Deleted.
+
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r291175. rdar://problem/88549631
 
     Fix WebContent jetsam that occurs when selecting text in a large e-mail

Modified: branches/safari-613-branch/Source/WebCore/dom/Element.cpp (291666 => 291667)


--- branches/safari-613-branch/Source/WebCore/dom/Element.cpp	2022-03-22 17:56:43 UTC (rev 291666)
+++ branches/safari-613-branch/Source/WebCore/dom/Element.cpp	2022-03-22 17:56:48 UTC (rev 291667)
@@ -3435,6 +3435,16 @@
         layer.establishesTopLayerWillChange();
     });
 
+    // We need to call Styleable::fromRenderer() while this element is still contained in
+    // Document::topLayerElements(), since Styleable::fromRenderer() relies on this to
+    // find the backdrop's associated element.
+    if (auto* renderer = this->renderer()) {
+        if (auto backdrop = renderer->backdropRenderer()) {
+            if (auto styleable = Styleable::fromRenderer(*backdrop))
+                styleable->cancelDeclarativeAnimations();
+        }
+    }
+
     document().removeTopLayerElement(*this);
     clearNodeFlag(NodeFlag::IsInTopLayer);
 

Modified: branches/safari-613-branch/Source/WebCore/style/Styleable.cpp (291666 => 291667)


--- branches/safari-613-branch/Source/WebCore/style/Styleable.cpp	2022-03-22 17:56:43 UTC (rev 291666)
+++ branches/safari-613-branch/Source/WebCore/style/Styleable.cpp	2022-03-22 17:56:48 UTC (rev 291667)
@@ -148,33 +148,6 @@
         removeDeclarativeAnimationFromListsForOwningElement(animation);
 }
 
-static void removeCSSAnimationCreatedByMarkup(const Styleable& styleable, CSSAnimation& cssAnimation)
-{
-    styleable.animationsCreatedByMarkup().remove(&cssAnimation);
-
-    if (!styleable.hasKeyframeEffects())
-        return;
-
-    auto& keyframeEffectStack = styleable.ensureKeyframeEffectStack();
-    auto* cssAnimationList = keyframeEffectStack.cssAnimationList();
-    if (!cssAnimationList || cssAnimationList->isEmpty())
-        return;
-
-    auto& backingAnimation = cssAnimation.backingAnimation();
-    for (size_t i = 0; i < cssAnimationList->size(); ++i) {
-        if (cssAnimationList->animation(i) == backingAnimation) {
-            // It is important we do not make a clone of the Animation references contained
-            // within cssAnimationList since sorting animations in compareCSSAnimations()
-            // makes pointer comparisons to distinguish between backing animations of various
-            // CSSAnimation objects.
-            auto newAnimationList = cssAnimationList->shallowCopy();
-            newAnimationList->remove(i);
-            keyframeEffectStack.setCSSAnimationList(WTFMove(newAnimationList));
-            return;
-        }
-    }
-}
-
 void Styleable::elementWasRemoved() const
 {
     cancelDeclarativeAnimations();
@@ -192,13 +165,15 @@
 {
     if (auto* animations = this->animations()) {
         for (auto& animation : *animations) {
-            if (is<DeclarativeAnimation>(animation)) {
-                if (is<CSSAnimation>(animation))
-                    removeCSSAnimationCreatedByMarkup(*this, downcast<CSSAnimation>(*animation));
+            if (is<DeclarativeAnimation>(animation))
                 downcast<DeclarativeAnimation>(*animation).cancelFromStyle();
-            }
         }
     }
+
+    if (auto* effectStack = keyframeEffectStack())
+        effectStack->setCSSAnimationList(nullptr);
+
+    setAnimationsCreatedByMarkup({ });
 }
 
 static bool keyframesRuleExistsForAnimation(Element& element, const Animation& animation, const String& animationName)
@@ -231,6 +206,7 @@
         for (auto& cssAnimation : animationsCreatedByMarkup())
             cssAnimation->cancelFromStyle();
         keyframeEffectStack.setCSSAnimationList(nullptr);
+        setAnimationsCreatedByMarkup({ });
         return;
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to