Update hover state in composed tree
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Nov 2018 16:17:44 +0000 (16:17 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Nov 2018 16:17:44 +0000 (16:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191860

Reviewed by Zalan Bujtas.

The code was already mostly switched over from render tree to composed tree.
This patch replaces the remaining common ancestor search code with a DOM based equivalent.

* dom/Document.cpp:
(WebCore::findNearestCommonComposedAncestor):
(WebCore::Document::updateHoverActiveState):
(WebCore::nearestCommonHoverAncestor): Deleted.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::hoverAncestor const): Deleted.
* rendering/RenderBlock.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::hoverAncestor const): Deleted.

No longer needed.

* rendering/RenderElement.h:

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

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h

index 4ae641d..0dc1824 100644 (file)
@@ -1,3 +1,27 @@
+2018-11-20  Antti Koivisto  <antti@apple.com>
+
+        Update hover state in composed tree
+        https://bugs.webkit.org/show_bug.cgi?id=191860
+
+        Reviewed by Zalan Bujtas.
+
+        The code was already mostly switched over from render tree to composed tree.
+        This patch replaces the remaining common ancestor search code with a DOM based equivalent.
+
+        * dom/Document.cpp:
+        (WebCore::findNearestCommonComposedAncestor):
+        (WebCore::Document::updateHoverActiveState):
+        (WebCore::nearestCommonHoverAncestor): Deleted.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::hoverAncestor const): Deleted.
+        * rendering/RenderBlock.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::hoverAncestor const): Deleted.
+
+        No longer needed.
+
+        * rendering/RenderElement.h:
+
 2018-11-20  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Measure run with non-breakable start/end.
index fe01e94..5c2ff13 100644 (file)
@@ -7136,18 +7136,22 @@ DocumentParserYieldToken::~DocumentParserYieldToken()
         parser->didEndYieldingParser();
 }
 
-static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
+static Element* findNearestCommonComposedAncestor(Element* elementA, Element* elementB)
 {
-    if (!obj1 || !obj2)
+    if (!elementA || !elementB)
         return nullptr;
 
-    for (RenderElement* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
-        for (RenderElement* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
-            if (currObj1 == currObj2)
-                return currObj1;
-        }
-    }
+    if (elementA == elementB)
+        return elementA;
+
+    HashSet<Element*> ancestorChain;
+    for (auto* element = elementA; element; element = element->parentElementInComposedTree())
+        ancestorChain.add(element);
 
+    for (auto* element = elementB; element; element = element->parentElementInComposedTree()) {
+        if (ancestorChain.contains(element))
+            return element;
+    }
     return nullptr;
 }
 
@@ -7208,26 +7212,21 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
 
     m_hoveredElement = newHoveredElement;
 
-    // We have two different objects. Fetch their renderers.
-    RenderElement* oldHoverObj = oldHoveredElement ? oldHoveredElement->renderer() : nullptr;
-    RenderElement* newHoverObj = newHoveredElement ? newHoveredElement->renderer() : nullptr;
-
-    // Locate the common ancestor render object for the two renderers.
-    RenderElement* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
+    auto* commonAncestor = findNearestCommonComposedAncestor(oldHoveredElement.get(), newHoveredElement);
 
     Vector<RefPtr<Element>, 32> elementsToRemoveFromChain;
     Vector<RefPtr<Element>, 32> elementsToAddToChain;
 
-    if (oldHoverObj != newHoverObj) {
+    if (oldHoveredElement != newHoveredElement) {
         for (auto* element = oldHoveredElement.get(); element; element = element->parentElementInComposedTree()) {
-            if (ancestor && ancestor->element() == element)
+            if (element == commonAncestor)
                 break;
             if (!mustBeInActiveChain || element->inActiveChain())
                 elementsToRemoveFromChain.append(element);
         }
         // Unset hovered nodes in sub frame documents if the old hovered node was a frame owner.
         if (is<HTMLFrameOwnerElement>(oldHoveredElement)) {
-            if (Document* contentDocument = downcast<HTMLFrameOwnerElement>(*oldHoveredElement).contentDocument())
+            if (auto* contentDocument = downcast<HTMLFrameOwnerElement>(*oldHoveredElement).contentDocument())
                 contentDocument->updateHoverActiveState(request, nullptr);
         }
     }
@@ -7244,7 +7243,7 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
     for (auto& element : elementsToAddToChain) {
         if (allowActiveChanges)
             element->setActive(true);
-        if (ancestor && element == ancestor->element())
+        if (element == commonAncestor)
             sawCommonAncestor = true;
         if (!sawCommonAncestor) {
             // Elements after the common hover ancestor does not change hover state, but are iterated over because they may change active state.
index 8df4066..1df5734 100644 (file)
@@ -2781,13 +2781,6 @@ LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject*
     return r;
 }
 
-RenderElement* RenderBlock::hoverAncestor() const
-{
-    if (auto* continuation = this->continuation())
-        return continuation;
-    return RenderBox::hoverAncestor();
-}
-
 void RenderBlock::updateDragState(bool dragOn)
 {
     RenderBox::updateDragState(dragOn);
index 8e806ed..4c6148b 100644 (file)
@@ -457,7 +457,6 @@ private:
     LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const final;
     const RenderStyle& outlineStyleForRepaint() const final;
 
-    RenderElement* hoverAncestor() const final;
     void updateDragState(bool dragOn) final;
 
     LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) final
index 4a1c0ee..01f387a 100644 (file)
@@ -974,11 +974,6 @@ void RenderElement::setNeedsSimplifiedNormalFlowLayout()
         setLayerNeedsFullRepaint();
 }
 
-RenderElement* RenderElement::hoverAncestor() const
-{
-    return parent();
-}
-
 static inline void paintPhase(RenderElement& element, PaintPhase phase, PaintInfo& paintInfo, const LayoutPoint& childPoint)
 {
     paintInfo.phase = phase;
index 09db1a4..d46dd33 100644 (file)
@@ -97,8 +97,6 @@ public:
     void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
 
-    virtual RenderElement* hoverAncestor() const;
-
     virtual void dirtyLinesFromChangedChild(RenderObject&) { }
 
     bool ancestorLineBoxDirty() const { return m_ancestorLineBoxDirty; }