Title: [163919] trunk/Source
Revision
163919
Author
enr...@apple.com
Date
2014-02-11 17:10:21 -0800 (Tue, 11 Feb 2014)

Log Message

Support WebSelections in WK2 on iOS.
https://bugs.webkit.org/show_bug.cgi?id=127015
<rdar://problem/15211964>

Reviewed by Benjamin Poulain.

Source/WebCore: 

Adding few exports.

* WebCore.exp.in:

Source/WebKit2: 

First step towards implementing block selections on iOS.
The main logic is in rangeForWebSelectionAtPosition that
decides whether we create a text or a block selection.

* Shared/ios/WKGestureTypes.h:
* UIProcess/API/ios/WKInteractionView.mm:
(toUIWKSelectionFlags):
(selectionChangedWithGesture):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::rangeForWebSelectionAtPosition):
(WebKit::WebPage::selectWithGesture):
(WebKit::WebPage::getPositionInformation):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (163918 => 163919)


--- trunk/Source/WebCore/ChangeLog	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebCore/ChangeLog	2014-02-12 01:10:21 UTC (rev 163919)
@@ -1,3 +1,15 @@
+2014-02-11  Enrica Casucci  <enr...@apple.com>
+
+        Support WebSelections in WK2 on iOS.
+        https://bugs.webkit.org/show_bug.cgi?id=127015
+        <rdar://problem/15211964>
+
+        Reviewed by Benjamin Poulain.
+
+        Adding few exports.
+
+        * WebCore.exp.in:
+
 2014-02-11  Andreas Kling  <akl...@apple.com>
 
         CTTE: RenderNamedFlowThread always has a WebKitNamedFlow.

Modified: trunk/Source/WebCore/WebCore.exp.in (163918 => 163919)


--- trunk/Source/WebCore/WebCore.exp.in	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebCore/WebCore.exp.in	2014-02-12 01:10:21 UTC (rev 163919)
@@ -1421,6 +1421,7 @@
 __ZN7WebCore10Pasteboard21createForCopyAndPasteEv
 __ZN7WebCore10TimeRanges13intersectWithEPKS0_
 __ZN7WebCore10TimeRangesC1Edd
+__ZN7WebCore13SelectionRectC1ERKNS_7IntRectEbi
 __ZNK3JSC8Bindings10RootObject12globalObjectEv
 __ZNK3WTF6String14createCFStringEv
 __ZNK7WebCore10Credential11hasPasswordEv
@@ -1487,6 +1488,7 @@
 __ZNK7WebCore11HistoryItem8referrerEv
 __ZNK7WebCore11HistoryItem9urlStringEv
 __ZNK7WebCore11HistoryItem9viewStateEv
+__ZNK7WebCore11RenderBlock25inlineElementContinuationEv
 __ZNK7WebCore11RenderLayer19absoluteBoundingBoxEv
 __ZNK7WebCore11RenderLayer24needsCompositedScrollingEv
 __ZNK7WebCore11RenderStyle11fontMetricsEv
@@ -1751,6 +1753,7 @@
 __ZNK7WebCore5Range9firstNodeEv
 __ZNK7WebCore5Range9textQuadsERN3WTF6VectorINS_9FloatQuadELm0ENS1_15CrashOnOverflowEEEbPNS0_20RangeInFixedPositionE
 __ZNK7WebCore5Range9textRectsERN3WTF6VectorINS_7IntRectELm0ENS1_15CrashOnOverflowEEEbPNS0_20RangeInFixedPositionE
+__ZNK7WebCore5Range23commonAncestorContainerERi
 __ZNK7WebCore6Chrome12createWindowEPNS_5FrameERKNS_16FrameLoadRequestERKNS_14WindowFeaturesERKNS_16NavigationActionE
 __ZNK7WebCore6Editor12selectedTextEv
 __ZNK7WebCore6Editor13canEditRichlyEv

Modified: trunk/Source/WebKit2/ChangeLog (163918 => 163919)


--- trunk/Source/WebKit2/ChangeLog	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebKit2/ChangeLog	2014-02-12 01:10:21 UTC (rev 163919)
@@ -1,3 +1,25 @@
+2014-02-11  Enrica Casucci  <enr...@apple.com>
+
+        Support WebSelections in WK2 on iOS.
+        https://bugs.webkit.org/show_bug.cgi?id=127015
+        <rdar://problem/15211964>
+
+        Reviewed by Benjamin Poulain.
+
+        First step towards implementing block selections on iOS.
+        The main logic is in rangeForWebSelectionAtPosition that
+        decides whether we create a text or a block selection.
+
+        * Shared/ios/WKGestureTypes.h:
+        * UIProcess/API/ios/WKInteractionView.mm:
+        (toUIWKSelectionFlags):
+        (selectionChangedWithGesture):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::rangeForWebSelectionAtPosition):
+        (WebKit::WebPage::selectWithGesture):
+        (WebKit::WebPage::getPositionInformation):
+
 2014-02-10  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Convert position:sticky and position:fixed properties to position:static and position:absolute upon copy

Modified: trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h (163918 => 163919)


--- trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h	2014-02-12 01:10:21 UTC (rev 163919)
@@ -69,6 +69,12 @@
     WKSheetActionSaveImage
 } WKSheetActions;
 
+typedef enum {
+    WKNone = 0,
+    WKWordIsNearTap = 1,
+    WKIsBlockSelection = 2
+} WKSelectionFlags;
+
 } // namespace WebKit
 
 #endif // WKGestureTypes_h

Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm (163918 => 163919)


--- trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm	2014-02-12 01:10:21 UTC (rev 163919)
@@ -1071,6 +1071,18 @@
     }
 }
 
+static inline UIWKSelectionFlags toUIWKSelectionFlags(WKSelectionFlags flag)
+{
+    switch (flag) {
+    case WKNone:
+        return UIWKNone;
+    case WKWordIsNearTap:
+        return UIWKWordIsNearTap;
+    case WKIsBlockSelection:
+        return UIWKIsBlockSelection;
+    }
+}
+
 static void selectionChangedWithGesture(const WebCore::IntPoint& point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, WKErrorRef error, void* context)
 {
     if (error) {
@@ -1079,11 +1091,10 @@
     }
     WKInteractionView *view = static_cast<WKInteractionView*>(context);
     ASSERT(view);
-    // FIXME: need to pass flags to selectionChangedWithGestureAt.
     if ([view webSelectionAssistant])
-        [(UIWKSelectionAssistant *)[view webSelectionAssistant] selectionChangedWithGestureAt:(CGPoint)point withGesture:toUIWKGestureType((WKGestureType)gestureType) withState:toUIGestureRecognizerState(static_cast<WKGestureRecognizerState>(gestureState))];
+        [(UIWKSelectionAssistant *)[view webSelectionAssistant] selectionChangedWithGestureAt:(CGPoint)point withGesture:toUIWKGestureType((WKGestureType)gestureType) withState:toUIGestureRecognizerState(static_cast<WKGestureRecognizerState>(gestureState)) withFlags:(toUIWKSelectionFlags((WKSelectionFlags)flags))];
     else
-        [(UIWKTextInteractionAssistant *)[view interactionAssistant] selectionChangedWithGestureAt:(CGPoint)point withGesture:toUIWKGestureType((WKGestureType)gestureType) withState:toUIGestureRecognizerState(static_cast<WKGestureRecognizerState>(gestureState))];
+        [(UIWKTextInteractionAssistant *)[view interactionAssistant] selectionChangedWithGestureAt:(CGPoint)point withGesture:toUIWKGestureType((WKGestureType)gestureType) withState:toUIGestureRecognizerState(static_cast<WKGestureRecognizerState>(gestureState)) withFlags:(toUIWKSelectionFlags((WKSelectionFlags)flags))];
 }
 
 static void selectionChangedWithTouch(const WebCore::IntPoint& point, uint32_t touch, WKErrorRef error, void* context)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (163918 => 163919)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2014-02-12 01:10:21 UTC (rev 163919)
@@ -45,6 +45,7 @@
 #include "Plugin.h"
 #include "SandboxExtension.h"
 #include "ShareableBitmap.h"
+#include "WKGestureTypes.h"
 #include "WebUndoStep.h"
 #include <WebCore/DictationAlternative.h>
 #include <WebCore/DragData.h>
@@ -724,6 +725,7 @@
 
 #if PLATFORM(IOS)
     static void convertSelectionRectsToRootView(WebCore::FrameView*, Vector<WebCore::SelectionRect>&);
+    PassRefPtr<WebCore::Range> rangeForWebSelectionAtPosition(const WebCore::IntPoint&, const WebCore::VisiblePosition&, WKSelectionFlags&);
 #endif
 #if !PLATFORM(MAC)
     static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
@@ -1068,6 +1070,7 @@
 
     WebCore::ViewportConfiguration m_viewportConfiguration;
     bool m_userHasChangedPageScaleFactor;
+    WebCore::IntSize m_blockSelectionDesiredSize;
 #endif
 
     WebInspectorClient* m_inspectorClient;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (163918 => 163919)


--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2014-02-12 00:22:01 UTC (rev 163918)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2014-02-12 01:10:21 UTC (rev 163919)
@@ -52,6 +52,7 @@
 #import <WebCore/Pasteboard.h>
 #import <WebCore/PlatformKeyboardEvent.h>
 #import <WebCore/PlatformMouseEvent.h>
+#import <WebCore/RenderBlock.h>
 #import <WebCore/RenderImage.h>
 #import <WebCore/ResourceBuffer.h>
 #import <WebCore/SharedBuffer.h>
@@ -63,6 +64,9 @@
 
 namespace WebKit {
 
+const int blockSelectionStartWidth = 100;
+const int blockSelectionStartHeight = 100;
+
 void WebPage::platformInitialize()
 {
     notImplemented();
@@ -412,6 +416,66 @@
     return constrainedPoint;
 }
 
+PassRefPtr<Range> WebPage::rangeForWebSelectionAtPosition(const IntPoint& point, const VisiblePosition& position, WKSelectionFlags& flags)
+{
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint((point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent | HitTestRequest::AllowChildFrameContent);
+
+    Node* currentNode = result.innerNode();
+    RefPtr<Range> range;
+    IntRect boundingRect;
+    ExceptionCode ec;
+
+    if (currentNode->isTextNode()) {
+        range = enclosingTextUnitOfGranularity(position, ParagraphGranularity, DirectionForward);
+        if (!range || range->collapsed(ec))
+            range = Range::create(currentNode->document(), position, position);
+        if (!range)
+            return nullptr;
+
+        Vector<SelectionRect> selectionRects;
+        range->collectSelectionRects(selectionRects);
+        unsigned size = selectionRects.size();
+
+        for (unsigned i = 0; i < size; i++) {
+            const IntRect &coreRect = selectionRects[i].rect();
+            if (i == 0)
+                boundingRect = coreRect;
+            else
+                boundingRect.unite(coreRect);
+        }
+        if (boundingRect.width() > m_blockSelectionDesiredSize.width() && boundingRect.height() > m_blockSelectionDesiredSize.height())
+            return wordRangeFromPosition(position);
+
+        currentNode = range->commonAncestorContainer(ec);
+    }
+
+    if (!currentNode->isElementNode())
+        currentNode = currentNode->parentElement();
+
+    Node* bestChoice = currentNode;
+    while (currentNode) {
+        boundingRect = currentNode->renderer()->absoluteBoundingBoxRect(true);
+        if (boundingRect.width() > m_blockSelectionDesiredSize.width() && boundingRect.height() > m_blockSelectionDesiredSize.height())
+            break;
+        bestChoice = currentNode;
+        currentNode = currentNode->parentElement();
+    }
+
+    if (!bestChoice)
+        return nullptr;
+
+    RenderObject* renderer = bestChoice->renderer();
+    if (renderer && renderer->childrenInline() && (renderer->isRenderBlock() && toRenderBlock(renderer)->inlineElementContinuation() == nil) && !renderer->isTable()) {
+        range = enclosingTextUnitOfGranularity(position, WordGranularity, DirectionBackward);
+        if (range && !range->collapsed(ec))
+            return range;
+    }
+    flags = WKIsBlockSelection;
+    range = Range::create(bestChoice->document());
+    range->selectNode(bestChoice, ec);
+    return range;
+}
+
 void WebPage::selectWithGesture(const IntPoint& point, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, uint64_t callbackID)
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();
@@ -424,6 +488,7 @@
         return;
     }
     RefPtr<Range> range;
+    WKSelectionFlags flags = WKNone;
     switch (static_cast<WKGestureType>(gestureType)) {
     case WKGestureOneFingerTap:
     {
@@ -514,8 +579,11 @@
         break;
 
     case WKGestureMakeWebSelection:
-        // FIXME: Here we should implement the logic for block selections.
-        range = wordRangeFromPosition(position);
+        if (static_cast<WKGestureRecognizerState>(gestureState) == WKGestureRecognizerStateBegan) {
+            m_blockSelectionDesiredSize.setWidth(blockSelectionStartWidth);
+            m_blockSelectionDesiredSize.setHeight(blockSelectionStartHeight);
+        }
+        range = rangeForWebSelectionAtPosition(point, position, flags);
         break;
 
     default:
@@ -524,7 +592,7 @@
     if (range)
         frame.selection().setSelectedRange(range.get(), position.affinity(), true);
 
-    send(Messages::WebPageProxy::GestureCallback(point, gestureType, gestureState, 0, callbackID));
+    send(Messages::WebPageProxy::GestureCallback(point, gestureType, gestureState, flags, callbackID));
     m_shouldReturnWordAtSelection = false;
 }
 
@@ -894,18 +962,10 @@
     if (!elementIsLinkOrImage) {
         HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint((point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent | HitTestRequest::AllowChildFrameContent);
         hitNode = result.innerNode();
-        if (hitNode && hitNode->isTextNode()) {
+        if (hitNode) {
             m_page->focusController().setFocusedFrame(result.innerNodeFrame());
-            FrameView* view = result.innerNodeFrame()->view();
-            VisiblePosition position = result.innerNodeFrame()->visiblePositionForPoint(view->rootViewToContents(point));
-            RefPtr<Range> range = wordRangeFromPosition(position);
-            if (range)
-                range->collectSelectionRects(info.selectionRects);
-            convertSelectionRectsToRootView(view, info.selectionRects);
-        } else {
-            // FIXME: implement the logic for the block selection.
+            info.selectionRects.append(SelectionRect(hitNode->renderer()->absoluteBoundingBoxRect(true), true, 0));
         }
-
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to