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;