Title: [295569] trunk
Revision
295569
Author
[email protected]
Date
2022-06-15 12:59:57 -0700 (Wed, 15 Jun 2022)

Log Message

Invalidate animation keyframes using container units on when container size changes
https://bugs.webkit.org/show_bug.cgi?id=241546

Reviewed by Antoine Quint.

Container size change also changes the interpretation of container units used in keyframes.

* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt:
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::invalidateForQueryContainerSizeChange):
(WebCore::Element::needsUpdateQueryContainerDependentStyle const):
(WebCore::Element::clearNeedsUpdateQueryContainerDependentStyle):
(WebCore::Element::invalidateForQueryContainerChange): Deleted.

Add a new bit that tells when a container has been resized.

* Source/WebCore/dom/Element.h:
* Source/WebCore/dom/Node.h:
* Source/WebCore/rendering/style/KeyframeList.cpp:
(WebCore::KeyframeList::usesContainerUnits const):

Check for container unit use.

* Source/WebCore/rendering/style/KeyframeList.h:
* Source/WebCore/style/StyleScope.cpp:
(WebCore::Style::Scope::updateQueryContainerState):
* Source/WebCore/style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::createAnimatedElementUpdate):

Invalidate the keyframes if needed when computing the style.

(WebCore::Style::TreeResolver::pushParent):

Track if the subtree is withing a resized container.

* Source/WebCore/style/StyleTreeResolver.h:
* Source/WebCore/style/Styleable.cpp:
(WebCore::Styleable::queryContainerDidChange const):
* Source/WebCore/style/Styleable.h:

Canonical link: https://commits.webkit.org/251574@main

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt (295568 => 295569)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt	2022-06-15 19:59:57 UTC (rev 295569)
@@ -1,14 +1,14 @@
 
 PASS Animation using cqw unit
-FAIL Animation using cqw unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqw unit responds to changing container size
 PASS Animation using cqh unit
-FAIL Animation using cqh unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqh unit responds to changing container size
 PASS Animation using cqi unit
-FAIL Animation using cqi unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqi unit responds to changing container size
 PASS Animation using cqb unit
-FAIL Animation using cqb unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqb unit responds to changing container size
 PASS Animation using cqmin unit
-FAIL Animation using cqmin unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqmin unit responds to changing container size
 PASS Animation using cqmax unit
-FAIL Animation using cqmax unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqmax unit responds to changing container size
 

Modified: trunk/Source/WebCore/dom/Element.cpp (295568 => 295569)


--- trunk/Source/WebCore/dom/Element.cpp	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/dom/Element.cpp	2022-06-15 19:59:57 UTC (rev 295569)
@@ -2265,12 +2265,23 @@
     Node::invalidateStyle(Style::Validity::SubtreeInvalid);
 }
 
-void Element::invalidateForQueryContainerChange()
+void Element::invalidateForQueryContainerSizeChange()
 {
     // FIXME: Ideally we would just recompute things that are actually affected by containers queries within the subtree.
     Node::invalidateStyle(Style::Validity::SubtreeInvalid);
+    setNodeFlag(NodeFlag::NeedsUpdateQueryContainerDependentStyle);
 }
 
+bool Element::needsUpdateQueryContainerDependentStyle() const
+{
+    return hasNodeFlag(NodeFlag::NeedsUpdateQueryContainerDependentStyle);
+}
+
+void Element::clearNeedsUpdateQueryContainerDependentStyle()
+{
+    clearNodeFlag(NodeFlag::NeedsUpdateQueryContainerDependentStyle);
+}
+
 void Element::invalidateEventListenerRegions()
 {
     // Event listener region is updated via style update.

Modified: trunk/Source/WebCore/dom/Element.h (295568 => 295569)


--- trunk/Source/WebCore/dom/Element.h	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/dom/Element.h	2022-06-15 19:59:57 UTC (rev 295569)
@@ -639,8 +639,11 @@
 
     void invalidateStyleInternal();
     void invalidateStyleForSubtreeInternal();
-    void invalidateForQueryContainerChange();
+    void invalidateForQueryContainerSizeChange();
 
+    bool needsUpdateQueryContainerDependentStyle() const;
+    void clearNeedsUpdateQueryContainerDependentStyle();
+
     void invalidateEventListenerRegions();
 
     bool hasDisplayContents() const;

Modified: trunk/Source/WebCore/dom/Node.h (295568 => 295569)


--- trunk/Source/WebCore/dom/Node.h	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/dom/Node.h	2022-06-15 19:59:57 UTC (rev 295569)
@@ -582,9 +582,10 @@
         IsComputedStyleInvalidFlag = 1 << 25,
         HasShadowRootContainingSlots = 1 << 26,
         IsInTopLayer = 1 << 27,
-        NeedsSVGRendererUpdate = 1 << 28
+        NeedsSVGRendererUpdate = 1 << 28,
+        NeedsUpdateQueryContainerDependentStyle = 1 << 29,
 
-        // Bits 29-31 are free.
+        // Bits 30-31 are free.
     };
 
     enum class TabIndexState : uint8_t {

Modified: trunk/Source/WebCore/rendering/style/KeyframeList.cpp (295568 => 295569)


--- trunk/Source/WebCore/rendering/style/KeyframeList.cpp	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/rendering/style/KeyframeList.cpp	2022-06-15 19:59:57 UTC (rev 295569)
@@ -217,4 +217,14 @@
     return false;
 }
 
+bool KeyframeList::usesContainerUnits() const
+{
+    for (auto& keyframe : m_keyframes) {
+        if (keyframe.style()->usesContainerUnits())
+            return true;
+    }
+    return false;
+}
+
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/style/KeyframeList.h (295568 => 295569)


--- trunk/Source/WebCore/rendering/style/KeyframeList.h	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/rendering/style/KeyframeList.h	2022-06-15 19:59:57 UTC (rev 295569)
@@ -105,6 +105,8 @@
     auto begin() const { return m_keyframes.begin(); }
     auto end() const { return m_keyframes.end(); }
 
+    bool usesContainerUnits() const;
+
 private:
     AtomString m_animationName;
     Vector<KeyframeValue> m_keyframes; // Kept sorted by key.

Modified: trunk/Source/WebCore/style/StyleScope.cpp (295568 => 295569)


--- trunk/Source/WebCore/style/StyleScope.cpp	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/style/StyleScope.cpp	2022-06-15 19:59:57 UTC (rev 295569)
@@ -829,7 +829,7 @@
     }
 
     for (auto* toInvalidate : containersToInvalidate)
-        toInvalidate->invalidateForQueryContainerChange();
+        toInvalidate->invalidateForQueryContainerSizeChange();
 
     return !containersToInvalidate.isEmpty();
 }

Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (295568 => 295569)


--- trunk/Source/WebCore/style/StyleTreeResolver.cpp	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp	2022-06-15 19:59:57 UTC (rev 295569)
@@ -577,7 +577,9 @@
     auto& document = element.document();
     auto* oldStyle = element.renderOrDisplayContentsStyle(styleable.pseudoId);
 
-    OptionSet<AnimationImpact> animationImpact;
+    // FIXME: Something like this is also needed for viewport units.
+    if (oldStyle && parent().needsUpdateQueryContainerDependentStyle)
+        styleable.queryContainerDidChange();
 
     // First, we need to make sure that any new CSS animation occuring on this element has a matching WebAnimation
     // on the document timeline.
@@ -592,6 +594,8 @@
             styleable.updateCSSAnimations(oldStyle, *newStyle, resolutionContext);
     }
 
+    OptionSet<AnimationImpact> animationImpact;
+
     // Now we can update all Web animations, which will include CSS Animations as well
     // as animations created via the JS API.
     if (styleable.hasKeyframeEffects()) {
@@ -640,6 +644,9 @@
         parent.didPushScope = true;
     }
 
+    parent.needsUpdateQueryContainerDependentStyle = m_parentStack.last().needsUpdateQueryContainerDependentStyle || element.needsUpdateQueryContainerDependentStyle();
+    element.clearNeedsUpdateQueryContainerDependentStyle();
+
     m_parentStack.append(WTFMove(parent));
 }
 

Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (295568 => 295569)


--- trunk/Source/WebCore/style/StyleTreeResolver.h	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h	2022-06-15 19:59:57 UTC (rev 295569)
@@ -69,7 +69,7 @@
     enum class DescendantsToResolve : uint8_t { None, ChildrenWithExplicitInherit, Children, All };
     std::pair<ElementUpdate, DescendantsToResolve> resolveElement(Element&, ResolutionType);
 
-    static ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, const Styleable&, Change, const ResolutionContext&);
+    ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, const Styleable&, Change, const ResolutionContext&);
     std::optional<ElementUpdate> resolvePseudoElement(Element&, PseudoId, const ElementUpdate&);
     std::optional<ElementUpdate> resolveAncestorPseudoElement(Element&, PseudoId, const ElementUpdate&);
     std::unique_ptr<RenderStyle> resolveAncestorFirstLinePseudoElement(Element&, const ElementUpdate&);
@@ -95,6 +95,7 @@
         DescendantsToResolve descendantsToResolve { DescendantsToResolve::None };
         bool didPushScope { false };
         bool resolvedFirstLineAndLetterChild { false };
+        bool needsUpdateQueryContainerDependentStyle { false };
 
         Parent(Document&);
         Parent(Element&, const RenderStyle&, Change, DescendantsToResolve);

Modified: trunk/Source/WebCore/style/Styleable.cpp (295568 => 295569)


--- trunk/Source/WebCore/style/Styleable.cpp	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/style/Styleable.cpp	2022-06-15 19:59:57 UTC (rev 295569)
@@ -625,4 +625,19 @@
         updateCSSTransitionsForStyleableAndProperty(*this, property, currentStyle, newStyle, generationTime);
 }
 
+void Styleable::queryContainerDidChange() const
+{
+    auto* animations = this->animations();
+    if (!animations)
+        return;
+    for (auto animation : *animations) {
+        auto* cssAnimation = dynamicDowncast<CSSAnimation>(animation.get());
+        if (!cssAnimation)
+            continue;
+        auto* keyframeEffect = dynamicDowncast<KeyframeEffect>(cssAnimation->effect());
+        if (keyframeEffect && keyframeEffect->blendingKeyframes().usesContainerUnits())
+            cssAnimation->keyframesRuleDidChange();
+    }
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/style/Styleable.h (295568 => 295569)


--- trunk/Source/WebCore/style/Styleable.h	2022-06-15 19:28:01 UTC (rev 295568)
+++ trunk/Source/WebCore/style/Styleable.h	2022-06-15 19:59:57 UTC (rev 295569)
@@ -161,6 +161,8 @@
         element.keyframesRuleDidChange(pseudoId);
     }
 
+    void queryContainerDidChange() const;
+
     bool animationListContainsNewlyValidAnimation(const AnimationList&) const;
 
     void elementWasRemoved() const;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to