Title: [200162] trunk/Source/WebCore
Revision
200162
Author
enr...@apple.com
Date
2016-04-27 16:53:08 -0700 (Wed, 27 Apr 2016)

Log Message

Refactor findExplodedTextNodeAtPoint to move core functionality in RenderBlockFlow.
https://bugs.webkit.org/show_bug.cgi?id=157076

Reviewed by Simon Fraser.

* bindings/objc/DOMUIKitExtensions.mm:
(-[DOMNode findExplodedTextNodeAtPoint:]):
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::findClosestTextAtAbsolutePoint):
* rendering/RenderBlockFlow.h:
* rendering/RenderText.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (200161 => 200162)


--- trunk/Source/WebCore/ChangeLog	2016-04-27 23:51:40 UTC (rev 200161)
+++ trunk/Source/WebCore/ChangeLog	2016-04-27 23:53:08 UTC (rev 200162)
@@ -1,3 +1,17 @@
+2016-04-27  Enrica Casucci  <enr...@apple.com>
+
+        Refactor findExplodedTextNodeAtPoint to move core functionality in RenderBlockFlow.
+        https://bugs.webkit.org/show_bug.cgi?id=157076
+
+        Reviewed by Simon Fraser.
+
+        * bindings/objc/DOMUIKitExtensions.mm:
+        (-[DOMNode findExplodedTextNodeAtPoint:]):
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::findClosestTextAtAbsolutePoint):
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderText.h:
+
 2016-04-27  Simon Fraser  <simon.fra...@apple.com>
 
         [iOS WK2] When determining tile size, check whether ancestor UIScrollViews are actually scrollable

Modified: trunk/Source/WebCore/bindings/objc/DOMUIKitExtensions.mm (200161 => 200162)


--- trunk/Source/WebCore/bindings/objc/DOMUIKitExtensions.mm	2016-04-27 23:51:40 UTC (rev 200161)
+++ trunk/Source/WebCore/bindings/objc/DOMUIKitExtensions.mm	2016-04-27 23:53:08 UTC (rev 200162)
@@ -253,75 +253,16 @@
 
 - (DOMNode *)findExplodedTextNodeAtPoint:(CGPoint)point
 {
-    // A light, non-recursive version of RenderBlock::positionForCoordinates that looks at
-    // whether a point lies within the gaps between its root line boxes, to be called against
-    // a node returned from elementAtPoint.  We make the assumption that either the node or one
-    // of its immediate children contains the root line boxes in question.
-    // See <rdar://problem/6824650> for context.
     RenderObject* renderer = core(self)->renderer();
     if (!is<RenderBlockFlow>(renderer))
         return nil;
 
-    RenderBlock* block = downcast<RenderBlockFlow>(renderer);
-    
-    FloatPoint absPoint(point);
-    FloatPoint localPoint = block->absoluteToLocal(absPoint);
+    RenderBlockFlow* block = downcast<RenderBlockFlow>(renderer);
+    RenderText* renderText = block->findClosestTextAtAbsolutePoint(point);
+    if (renderText && renderText->textNode())
+        return kit(renderText->textNode());
 
-    if (!block->childrenInline()) {
-        // Look among our immediate children for an alternate box that contains the point.
-        for (RenderBox* child = block->firstChildBox(); child; child = child->nextSiblingBox()) {
-            if (child->height() == 0 || child->style().visibility() != WebCore::VISIBLE || child->isFloatingOrOutOfFlowPositioned())
-                continue;
-            float top = child->y();
-            
-            RenderBox* nextChild = child->nextSiblingBox();
-            while (nextChild && nextChild->isFloatingOrOutOfFlowPositioned())
-                nextChild = nextChild->nextSiblingBox();
-            if (!nextChild) {
-                if (localPoint.y() >= top) {
-                    block = downcast<RenderBlock>(child);
-                    break;
-                }
-                continue;
-            }
-            
-            float bottom = nextChild->y();
-            
-            if (localPoint.y() >= top && localPoint.y() < bottom && is<RenderBlock>(*child)) {
-                block = downcast<RenderBlock>(child);
-                break;
-            }                
-        }
-        
-        if (!block->childrenInline())
-            return nil;
-        
-        localPoint = block->absoluteToLocal(absPoint);
-    }
-
-    RenderBlockFlow& blockFlow = downcast<RenderBlockFlow>(*block);
-    
-    // Only check the gaps between the root line boxes.  We deliberately ignore overflow because
-    // experience has shown that hit tests on an exploded text node can fail when within the
-    // overflow region.
-    for (RootInlineBox* current = blockFlow.firstRootBox(); current && current != blockFlow.lastRootBox(); current = current->nextRootBox()) {
-        float currentBottom = current->y() + current->logicalHeight();
-        if (localPoint.y() < currentBottom)
-            return nil;
-
-        RootInlineBox* next = current->nextRootBox();
-        float nextTop = next->y();
-        if (localPoint.y() < nextTop) {
-            InlineBox* inlineBox = current->closestLeafChildForLogicalLeftPosition(localPoint.x());
-            if (inlineBox && inlineBox->behavesLikeText() && is<RenderText>(inlineBox->renderer())) {
-                RenderText& renderText = downcast<RenderText>(inlineBox->renderer());
-                if (renderText.textNode())
-                    return kit(renderText.textNode());
-            }
-        }
-
-    }
-    return nil;    
+    return nil;
 }
 
 @end

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (200161 => 200162)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2016-04-27 23:51:40 UTC (rev 200161)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2016-04-27 23:53:08 UTC (rev 200162)
@@ -3356,6 +3356,71 @@
     return createLegacyEditingPosition(textBox.renderer().nonPseudoNode(), start ? textBox.start() : textBox.start() + textBox.len());
 }
 
+RenderText* RenderBlockFlow::findClosestTextAtAbsolutePoint(const FloatPoint& point)
+{
+    // A light, non-recursive version of RenderBlock::positionForCoordinates that looks at
+    // whether a point lies within the gaps between its root line boxes, to be called against
+    // a node returned from elementAtPoint. We make the assumption that either the node or one
+    // of its immediate children contains the root line boxes in question.
+    // See <rdar://problem/6824650> for context.
+    
+    RenderBlock* block = this;
+    
+    FloatPoint localPoint = block->absoluteToLocal(point);
+    
+    if (!block->childrenInline()) {
+        // Look among our immediate children for an alternate box that contains the point.
+        for (RenderBox* child = block->firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (!child->height() || child->style().visibility() != WebCore::VISIBLE || child->isFloatingOrOutOfFlowPositioned())
+                continue;
+            float top = child->y();
+            
+            RenderBox* nextChild = child->nextSiblingBox();
+            while (nextChild && nextChild->isFloatingOrOutOfFlowPositioned())
+                nextChild = nextChild->nextSiblingBox();
+            if (!nextChild) {
+                if (localPoint.y() >= top) {
+                    block = downcast<RenderBlock>(child);
+                    break;
+                }
+                continue;
+            }
+            
+            float bottom = nextChild->y();
+            
+            if (localPoint.y() >= top && localPoint.y() < bottom && is<RenderBlock>(*child)) {
+                block = downcast<RenderBlock>(child);
+                break;
+            }
+        }
+        
+        if (!block->childrenInline())
+            return nullptr;
+        
+        localPoint = block->absoluteToLocal(point);
+    }
+    
+    RenderBlockFlow& blockFlow = downcast<RenderBlockFlow>(*block);
+    
+    // Only check the gaps between the root line boxes. We deliberately ignore overflow because
+    // experience has shown that hit tests on an exploded text node can fail when within the
+    // overflow region.
+    for (RootInlineBox* current = blockFlow.firstRootBox(); current && current != blockFlow.lastRootBox(); current = current->nextRootBox()) {
+        float currentBottom = current->y() + current->logicalHeight();
+        if (localPoint.y() < currentBottom)
+            return nullptr;
+        
+        RootInlineBox* next = current->nextRootBox();
+        float nextTop = next->y();
+        if (localPoint.y() < nextTop) {
+            InlineBox* inlineBox = current->closestLeafChildForLogicalLeftPosition(localPoint.x());
+            if (inlineBox && inlineBox->behavesLikeText() && is<RenderText>(inlineBox->renderer()))
+                return &downcast<RenderText>(inlineBox->renderer());
+        }
+    }
+    return nullptr;
+}
+
 VisiblePosition RenderBlockFlow::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents, const RenderRegion* region)
 {
     ASSERT(childrenInline());

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (200161 => 200162)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2016-04-27 23:51:40 UTC (rev 200161)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2016-04-27 23:53:08 UTC (rev 200162)
@@ -394,6 +394,7 @@
     void updateStylesForColumnChildren();
 
     bool needsLayoutAfterRegionRangeChange() const override;
+    WEBCORE_EXPORT RenderText* findClosestTextAtAbsolutePoint(const FloatPoint&);
 
 protected:
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;

Modified: trunk/Source/WebCore/rendering/RenderText.h (200161 => 200162)


--- trunk/Source/WebCore/rendering/RenderText.h	2016-04-27 23:51:40 UTC (rev 200161)
+++ trunk/Source/WebCore/rendering/RenderText.h	2016-04-27 23:53:08 UTC (rev 200162)
@@ -44,7 +44,7 @@
 
     const char* renderName() const override;
 
-    Text* textNode() const;
+    WEBCORE_EXPORT Text* textNode() const;
 
     virtual bool isTextFragment() const;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to