Title: [287939] trunk/Source/WebCore
Revision
287939
Author
[email protected]
Date
2022-01-12 11:18:26 -0800 (Wed, 12 Jan 2022)

Log Message

Correctly dirty z-order lists when showing a modal dialog
https://bugs.webkit.org/show_bug.cgi?id=232762
<rdar://problem/85082354>

Reviewed by Alan Bujtas.

When showing a dialog element which is split into continuations, we need to ensure
to call establishesTopLayerWillChange()/establishesTopLayerDidChange() on the
layers of all the continuation renderers.

* dom/Element.cpp:
(WebCore::forEachRenderLayer): Call the provided function on the layers for all
the associated render objects. It's a little cumbersome because layers relate to
RenderLayerModelObject, but continuations relate to RenderBoxModelObject.
(WebCore::Element::addToTopLayer):
(WebCore::Element::removeFromTopLayer):
(WebCore::renderLayerForElement): Deleted.
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::forRendererAndContinuations):
* rendering/RenderBoxModelObject.h: Provider a static helper to call a function
on a renderer and all its continuations, if any.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287938 => 287939)


--- trunk/Source/WebCore/ChangeLog	2022-01-12 19:05:44 UTC (rev 287938)
+++ trunk/Source/WebCore/ChangeLog	2022-01-12 19:18:26 UTC (rev 287939)
@@ -1,3 +1,27 @@
+2022-01-11  Simon Fraser  <[email protected]>
+
+        Correctly dirty z-order lists when showing a modal dialog
+        https://bugs.webkit.org/show_bug.cgi?id=232762
+        <rdar://problem/85082354>
+
+        Reviewed by Alan Bujtas.
+
+        When showing a dialog element which is split into continuations, we need to ensure
+        to call establishesTopLayerWillChange()/establishesTopLayerDidChange() on the
+        layers of all the continuation renderers.
+
+        * dom/Element.cpp:
+        (WebCore::forEachRenderLayer): Call the provided function on the layers for all
+        the associated render objects. It's a little cumbersome because layers relate to
+        RenderLayerModelObject, but continuations relate to RenderBoxModelObject. 
+        (WebCore::Element::addToTopLayer):
+        (WebCore::Element::removeFromTopLayer):
+        (WebCore::renderLayerForElement): Deleted.
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::forRendererAndContinuations):
+        * rendering/RenderBoxModelObject.h: Provider a static helper to call a function
+        on a renderer and all its continuations, if any.
+
 2022-01-12  Sam Weinig  <[email protected]>
 
         Add some functions to Color to make debugging using color indicators easier

Modified: trunk/Source/WebCore/dom/Element.cpp (287938 => 287939)


--- trunk/Source/WebCore/dom/Element.cpp	2022-01-12 19:05:44 UTC (rev 287938)
+++ trunk/Source/WebCore/dom/Element.cpp	2022-01-12 19:18:26 UTC (rev 287939)
@@ -3381,12 +3381,24 @@
         child.ancestorWillEnterFullscreen();
 }
 
-static inline RenderLayer* renderLayerForElement(Element& element)
+static void forEachRenderLayer(Element& element, const std::function<void(RenderLayer&)>& function)
 {
     auto* renderer = element.renderer();
-    if (!renderer || !renderer->hasLayer() || !is<RenderLayerModelObject>(renderer))
-        return nullptr;
-    return downcast<RenderLayerModelObject>(*renderer).layer();
+    if (!renderer || !is<RenderLayerModelObject>(renderer))
+        return;
+        
+    auto& layerModelObject = downcast<RenderLayerModelObject>(*renderer);
+
+    if (!is<RenderBoxModelObject>(layerModelObject)) {
+        if (layerModelObject.hasLayer())
+            function(*layerModelObject.layer());
+        return;
+    }
+
+    RenderBoxModelObject::forRendererAndContinuations(downcast<RenderBoxModelObject>(*renderer), [function](RenderBoxModelObject& renderer) {
+        if (renderer.hasLayer())
+            function(*renderer.layer());
+    });
 }
 
 void Element::addToTopLayer()
@@ -3394,8 +3406,9 @@
     RELEASE_ASSERT(!isInTopLayer());
     ScriptDisallowedScope scriptDisallowedScope;
 
-    if (auto* layer = renderLayerForElement(*this))
-        layer->establishesTopLayerWillChange();
+    forEachRenderLayer(*this, [](RenderLayer& layer) {
+        layer.establishesTopLayerWillChange();
+    });
 
     document().addTopLayerElement(*this);
     setNodeFlag(NodeFlag::IsInTopLayer);
@@ -3405,8 +3418,9 @@
     if (document().documentElement())
         document().documentElement()->invalidateStyleInternal();
 
-    if (auto* layer = renderLayerForElement(*this))
-        layer->establishesTopLayerDidChange();
+    forEachRenderLayer(*this, [](RenderLayer& layer) {
+        layer.establishesTopLayerDidChange();
+    });
 }
 
 void Element::removeFromTopLayer()
@@ -3414,8 +3428,9 @@
     RELEASE_ASSERT(isInTopLayer());
     ScriptDisallowedScope scriptDisallowedScope;
 
-    if (auto* layer = renderLayerForElement(*this))
-        layer->establishesTopLayerWillChange();
+    forEachRenderLayer(*this, [](RenderLayer& layer) {
+        layer.establishesTopLayerWillChange();
+    });
 
     document().removeTopLayerElement(*this);
     clearNodeFlag(NodeFlag::IsInTopLayer);
@@ -3427,8 +3442,9 @@
     if (auto* modalElement = document().activeModalDialog())
         modalElement->invalidateStyleInternal();
 
-    if (auto* layer = renderLayerForElement(*this))
-        layer->establishesTopLayerDidChange();
+    forEachRenderLayer(*this, [](RenderLayer& layer) {
+        layer.establishesTopLayerDidChange();
+    });
 }
 
 static PseudoElement* beforeOrAfterPseudoElement(const Element& host, PseudoId pseudoElementSpecifier)

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (287938 => 287939)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2022-01-12 19:05:44 UTC (rev 287938)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2022-01-12 19:18:26 UTC (rev 287939)
@@ -2609,6 +2609,19 @@
     return nullptr;
 }
 
+void RenderBoxModelObject::forRendererAndContinuations(RenderBoxModelObject& renderer, const std::function<void(RenderBoxModelObject&)>& function)
+{
+    function(renderer);
+    if (!renderer.hasContinuationChainNode())
+        return;
+
+    for (auto* next = continuationChainNodeMap().get(&renderer)->next; next; next = next->next) {
+        if (!next->renderer)
+            continue;
+        function(*next->renderer);
+    }
+}
+
 RenderBoxModelObject::ContinuationChainNode* RenderBoxModelObject::continuationChainNode() const
 {
     return continuationChainNodeMap().get(this);

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (287938 => 287939)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2022-01-12 19:05:44 UTC (rev 287938)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2022-01-12 19:18:26 UTC (rev 287939)
@@ -233,7 +233,9 @@
 
     RenderBoxModelObject* continuation() const;
     WEBCORE_EXPORT RenderInline* inlineContinuation() const;
-    
+
+    static void forRendererAndContinuations(RenderBoxModelObject&, const std::function<void(RenderBoxModelObject&)>&);
+
     void insertIntoContinuationChainAfter(RenderBoxModelObject&);
     void removeFromContinuationChain();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to