Title: [289457] trunk/Source/WebCore
Revision
289457
Author
[email protected]
Date
2022-02-08 23:35:37 -0800 (Tue, 08 Feb 2022)

Log Message

[CSS Container Queries] Track query containers so they can be invalidated on size change
https://bugs.webkit.org/show_bug.cgi?id=236297

Reviewed by Alan Bujtas.

Add container size tracking.

* dom/Document.cpp:
(WebCore::Document::updateLayout):
* dom/Element.cpp:
(WebCore::Element::invalidateForQueryContainerChange):
* dom/Element.h:
* page/FrameView.cpp:
(WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::willBeDestroyed):
(WebCore::RenderBox::styleWillChange):
* rendering/RenderView.cpp:
(WebCore::RenderView::registerContainerQueryBox):
(WebCore::RenderView::unregisterContainerQueryBox):
* rendering/RenderView.h:
* style/StyleScope.cpp:
(WebCore::Style::Scope::updateQueryContainerState):

Save the sizes after layout and invalidate if needed.

* style/StyleScope.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (289456 => 289457)


--- trunk/Source/WebCore/ChangeLog	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/ChangeLog	2022-02-09 07:35:37 UTC (rev 289457)
@@ -1,3 +1,33 @@
+2022-02-08  Antti Koivisto  <[email protected]>
+
+        [CSS Container Queries] Track query containers so they can be invalidated on size change
+        https://bugs.webkit.org/show_bug.cgi?id=236297
+
+        Reviewed by Alan Bujtas.
+
+        Add container size tracking.
+
+        * dom/Document.cpp:
+        (WebCore::Document::updateLayout):
+        * dom/Element.cpp:
+        (WebCore::Element::invalidateForQueryContainerChange):
+        * dom/Element.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::willBeDestroyed):
+        (WebCore::RenderBox::styleWillChange):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::registerContainerQueryBox):
+        (WebCore::RenderView::unregisterContainerQueryBox):
+        * rendering/RenderView.h:
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::updateQueryContainerState):
+
+        Save the sizes after layout and invalidate if needed.
+
+        * style/StyleScope.h:
+
 2022-02-08  Antoine Quint  <[email protected]>
 
         Move DocumentTimeline::runningAnimationsForRendererAreAllAccelerated() to Styleable

Modified: trunk/Source/WebCore/dom/Document.cpp (289456 => 289457)


--- trunk/Source/WebCore/dom/Document.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/dom/Document.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -2198,9 +2198,15 @@
 
     StackStats::LayoutCheckPoint layoutCheckPoint;
 
-    // Only do a layout if changes have occurred that make it necessary.      
-    if (frameView && renderView() && (frameView->layoutContext().isLayoutPending() || renderView()->needsLayout()))
-        frameView->layoutContext().layout();
+    if (!frameView || !renderView())
+        return;
+    if (!frameView->layoutContext().isLayoutPending() && !renderView()->needsLayout())
+        return;
+
+    frameView->layoutContext().layout();
+
+    if (styleScope().updateQueryContainerState())
+        updateLayout();
 }
 
 void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)

Modified: trunk/Source/WebCore/dom/Element.cpp (289456 => 289457)


--- trunk/Source/WebCore/dom/Element.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/dom/Element.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -2130,6 +2130,12 @@
     Node::invalidateStyle(Style::Validity::SubtreeInvalid);
 }
 
+void Element::invalidateForQueryContainerChange()
+{
+    // FIXME: This doesn't really need to recompute the element style.
+    Node::invalidateStyle(Style::Validity::ElementInvalid);
+}
+
 void Element::invalidateEventListenerRegions()
 {
     // Event listener region is updated via style update.

Modified: trunk/Source/WebCore/dom/Element.h (289456 => 289457)


--- trunk/Source/WebCore/dom/Element.h	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/dom/Element.h	2022-02-09 07:35:37 UTC (rev 289457)
@@ -635,6 +635,7 @@
 
     void invalidateStyleInternal();
     void invalidateStyleForSubtreeInternal();
+    void invalidateForQueryContainerChange();
 
     void invalidateEventListenerRegions();
 

Modified: trunk/Source/WebCore/page/FrameView.cpp (289456 => 289457)


--- trunk/Source/WebCore/page/FrameView.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/page/FrameView.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -4539,6 +4539,7 @@
                 didWork = true;
             if (view->needsLayout()) {
                 view->layoutContext().layout();
+                view->frame().document()->styleScope().updateQueryContainerState();
                 didWork = true;
             }
         }

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (289456 => 289457)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -173,8 +173,12 @@
     view().unscheduleLazyRepaint(*this);
     removeControlStatesForRenderer(*this);
 
-    if (hasInitializedStyle() && style().hasSnapPosition())
-        view().unregisterBoxWithScrollSnapPositions(*this);
+    if (hasInitializedStyle()) {
+        if (style().hasSnapPosition())
+            view().unregisterBoxWithScrollSnapPositions(*this);
+        if (style().containerType() != ContainerType::None)
+            view().unregisterContainerQueryBox(*this);
+    }
 
     RenderBoxModelObject::willBeDestroyed();
 }
@@ -293,6 +297,11 @@
             view().unregisterBoxWithScrollSnapPositions(*this);
     }
 
+    if (newStyle.containerType() != ContainerType::None)
+        view().registerContainerQueryBox(*this);
+    else if (oldStyle && oldStyle->containerType() != ContainerType::None)
+        view().unregisterContainerQueryBox(*this);
+
     RenderBoxModelObject::styleWillChange(diff, newStyle);
 }
 

Modified: trunk/Source/WebCore/rendering/RenderView.cpp (289456 => 289457)


--- trunk/Source/WebCore/rendering/RenderView.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/rendering/RenderView.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -962,4 +962,14 @@
     m_boxesWithScrollSnapPositions.remove(&box);
 }
 
+void RenderView::registerContainerQueryBox(const RenderBox& box)
+{
+    m_containerQueryBoxes.add(box);
+}
+
+void RenderView::unregisterContainerQueryBox(const RenderBox& box)
+{
+    m_containerQueryBoxes.remove(box);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderView.h (289456 => 289457)


--- trunk/Source/WebCore/rendering/RenderView.h	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/rendering/RenderView.h	2022-02-09 07:35:37 UTC (rev 289457)
@@ -29,6 +29,7 @@
 #include <memory>
 #include <wtf/HashSet.h>
 #include <wtf/ListHashSet.h>
+#include <wtf/WeakHashSet.h>
 
 namespace WebCore {
 
@@ -204,6 +205,10 @@
     void unregisterBoxWithScrollSnapPositions(const RenderBox&);
     const HashSet<const RenderBox*>& boxesWithScrollSnapPositions() { return m_boxesWithScrollSnapPositions; }
 
+    void registerContainerQueryBox(const RenderBox&);
+    void unregisterContainerQueryBox(const RenderBox&);
+    const WeakHashSet<const RenderBox>& containerQueryBoxes() const { return m_containerQueryBoxes; }
+
 private:
     void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, OptionSet<MapCoordinatesMode>, bool* wasFixed) const override;
     const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
@@ -270,6 +275,7 @@
     Vector<RefPtr<RenderWidget>> m_protectedRenderWidgets;
 
     HashSet<const RenderBox*> m_boxesWithScrollSnapPositions;
+    WeakHashSet<const RenderBox> m_containerQueryBoxes;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/style/StyleScope.cpp (289456 => 289457)


--- trunk/Source/WebCore/style/StyleScope.cpp	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/style/StyleScope.cpp	2022-02-09 07:35:37 UTC (rev 289457)
@@ -41,6 +41,7 @@
 #include "InspectorInstrumentation.h"
 #include "Logging.h"
 #include "ProcessingInstruction.h"
+#include "RenderView.h"
 #include "SVGElementTypeHelpers.h"
 #include "SVGStyleElement.h"
 #include "Settings.h"
@@ -782,6 +783,34 @@
     return m_shadowRoot && m_shadowRoot->mode() == ShadowRootMode::UserAgent;
 }
 
+bool Scope::updateQueryContainerState()
+{
+    ASSERT(!m_shadowRoot);
+    ASSERT(m_document.renderView());
+
+    auto previousStates = WTFMove(m_queryContainerStates);
+    m_queryContainerStates.clear();
+
+    Vector<Element*> changedContainers;
+
+    for (auto& containerRenderer : m_document.renderView()->containerQueryBoxes()) {
+        auto* containerElement = containerRenderer.element();
+        if (!containerElement)
+            continue;
+        auto size = containerRenderer.size();
+        auto it = previousStates.find(*containerElement);
+        bool changed = it == previousStates.end() || it->value != size;
+        if (changed)
+            changedContainers.append(containerElement);
+        m_queryContainerStates.add(*containerElement, size);
+    }
+
+    for (auto* toInvalidate : changedContainers)
+        toInvalidate->invalidateForQueryContainerChange();
+
+    return !changedContainers.isEmpty();
+}
+
 HTMLSlotElement* assignedSlotForScopeOrdinal(const Element& element, ScopeOrdinal scopeOrdinal)
 {
     ASSERT(scopeOrdinal >= ScopeOrdinal::FirstSlot);

Modified: trunk/Source/WebCore/style/StyleScope.h (289456 => 289457)


--- trunk/Source/WebCore/style/StyleScope.h	2022-02-09 06:51:25 UTC (rev 289456)
+++ trunk/Source/WebCore/style/StyleScope.h	2022-02-09 07:35:37 UTC (rev 289457)
@@ -27,6 +27,7 @@
 
 #pragma once
 
+#include "LayoutSize.h"
 #include "MediaQueryEvaluator.h"
 #include "StyleScopeOrdinal.h"
 #include "Timer.h"
@@ -38,6 +39,7 @@
 #include <wtf/ListHashSet.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/WeakHashMap.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -127,6 +129,8 @@
     static Scope& forNode(Node&);
     static Scope* forOrdinal(Element&, ScopeOrdinal);
 
+    bool updateQueryContainerState();
+
 private:
     Scope& documentScope();
     bool isForUserAgentShadowTree() const;
@@ -201,6 +205,7 @@
     bool m_isUpdatingStyleResolver { false };
 
     std::optional<MediaQueryViewportState> m_viewportStateOnPreviousMediaQueryEvaluation;
+    WeakHashMap<Element, LayoutSize> m_queryContainerStates;
 
     // FIXME: These (and some things above) are only relevant for the root scope.
     HashMap<ResolverSharingKey, Ref<Resolver>> m_sharedShadowTreeResolvers;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to