<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[167119] tags/Safari-538.28.2/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/167119">167119</a></dd>
<dt>Author</dt> <dd>mitz@apple.com</dd>
<dt>Date</dt> <dd>2014-04-11 02:23:01 -0700 (Fri, 11 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/167096">r167096</a>.

    2014-04-10  Enrica Casucci  &lt;enrica@apple.com&gt;

[iOS WebKit2] Support phraseboundary gesture recognizer for CJK.
https://bugs.webkit.org/show_bug.cgi?id=131493
&lt;rdar://problem/16319583&gt;

Reviewed by Benjamin Poulain.

On iOS it is possible with a gesture to change the selection
within the marked text.
Changing the selection triggers also the update of the inline candidates
over the keyboard area.
The patch adds the logic to decide whether the gesture can begin
as well as the code for the movement of
the selection within the marked range.
The gesture is allowed to start within a given radius from the marked
area.

* Shared/InteractionInformationAtPosition.cpp:
(WebKit::InteractionInformationAtPosition::encode):
(WebKit::InteractionInformationAtPosition::decode):
* Shared/InteractionInformationAtPosition.h:
(WebKit::InteractionInformationAtPosition::InteractionInformationAtPosition):
* Shared/ios/GestureTypes.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::editorStateChanged):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView pointIsNearMarkedText:]):
(toGestureType):
(toUIWKGestureType):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::selectWithGesture):
(WebKit::WebPage::getPositionInformation):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#tagsSafari538282SourceWebKit2ChangeLog">tags/Safari-538.28.2/Source/WebKit2/ChangeLog</a></li>
<li><a href="#tagsSafari538282SourceWebKit2SharedInteractionInformationAtPositioncpp">tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp</a></li>
<li><a href="#tagsSafari538282SourceWebKit2SharedInteractionInformationAtPositionh">tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.h</a></li>
<li><a href="#tagsSafari538282SourceWebKit2SharediosGestureTypesh">tags/Safari-538.28.2/Source/WebKit2/Shared/ios/GestureTypes.h</a></li>
<li><a href="#tagsSafari538282SourceWebKit2UIProcessWebPageProxycpp">tags/Safari-538.28.2/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#tagsSafari538282SourceWebKit2UIProcessiosWKContentViewInteractionmm">tags/Safari-538.28.2/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#tagsSafari538282SourceWebKit2WebProcessWebPageiosWebPageIOSmm">tags/Safari-538.28.2/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="tagsSafari538282SourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/ChangeLog (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/ChangeLog        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/ChangeLog        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2014-04-11  Dan Bernstein  &lt;mitz@apple.com&gt;
+
+        Merged r167096.
+
+    2014-04-10  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        [iOS WebKit2] Support phraseboundary gesture recognizer for CJK.
+        https://bugs.webkit.org/show_bug.cgi?id=131493
+        &lt;rdar://problem/16319583&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        On iOS it is possible with a gesture to change the selection
+        within the marked text.
+        Changing the selection triggers also the update of the inline candidates
+        over the keyboard area.
+        The patch adds the logic to decide whether the gesture can begin
+        as well as the code for the movement of
+        the selection within the marked range.
+        The gesture is allowed to start within a given radius from the marked
+        area.
+
+        * Shared/InteractionInformationAtPosition.cpp:
+        (WebKit::InteractionInformationAtPosition::encode):
+        (WebKit::InteractionInformationAtPosition::decode):
+        * Shared/InteractionInformationAtPosition.h:
+        (WebKit::InteractionInformationAtPosition::InteractionInformationAtPosition):
+        * Shared/ios/GestureTypes.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::editorStateChanged):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView pointIsNearMarkedText:]):
+        (toGestureType):
+        (toUIWKGestureType):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::selectWithGesture):
+        (WebKit::WebPage::getPositionInformation):
+
</ins><span class="cx"> 2014-04-09  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix build failure when #if USE(XPC_SERVICES) is false.
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2SharedInteractionInformationAtPositioncpp"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx">     encoder &lt;&lt; point;
</span><span class="cx">     encoder &lt;&lt; nodeAtPositionIsAssistedNode;
</span><span class="cx">     encoder &lt;&lt; isSelectable;
</span><ins>+    encoder &lt;&lt; isNearMarkedText;
</ins><span class="cx">     encoder &lt;&lt; clickableElementName;
</span><span class="cx">     encoder &lt;&lt; url;
</span><span class="cx">     encoder &lt;&lt; title;
</span><span class="lines">@@ -54,6 +55,9 @@
</span><span class="cx">     if (!decoder.decode(result.isSelectable))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.isNearMarkedText))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.clickableElementName))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2SharedInteractionInformationAtPositionh"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.h (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -38,12 +38,14 @@
</span><span class="cx">     InteractionInformationAtPosition()
</span><span class="cx">         : nodeAtPositionIsAssistedNode(false)
</span><span class="cx">         , isSelectable(false)
</span><ins>+        , isNearMarkedText(false)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     WebCore::IntPoint point;
</span><span class="cx">     bool nodeAtPositionIsAssistedNode;
</span><span class="cx">     bool isSelectable;
</span><ins>+    bool isNearMarkedText;
</ins><span class="cx">     String clickableElementName;
</span><span class="cx">     String url;
</span><span class="cx">     String title;
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2SharediosGestureTypesh"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/Shared/ios/GestureTypes.h (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/Shared/ios/GestureTypes.h        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/Shared/ios/GestureTypes.h        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -42,7 +42,8 @@
</span><span class="cx">     TwoFingerSingleTap,
</span><span class="cx">     TwoFingerRangedSelectGesture,
</span><span class="cx">     TapOnLinkWithGesture,
</span><del>-    MakeWebSelection
</del><ins>+    MakeWebSelection,
+    PhraseBoundary
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum class SelectionTouch {
</span><span class="lines">@@ -73,6 +74,7 @@
</span><span class="cx">     None = 0,
</span><span class="cx">     WordIsNearTap = 1 &lt;&lt; 0,
</span><span class="cx">     IsBlockSelection = 1 &lt;&lt; 1,
</span><ins>+    PhraseBoundaryChanged = 1 &lt;&lt; 2,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum class SelectionHandlePosition {
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/UIProcess/WebPageProxy.cpp (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -3156,10 +3156,9 @@
</span><span class="cx">         m_pageClient.notifyInputContextAboutDiscardedComposition();
</span><span class="cx">     }
</span><span class="cx"> #elif PLATFORM(IOS)
</span><del>-    if (!editorState.hasComposition) {
-        // We need to notify the client on iOS to make sure the selection is redrawn.
-        notifyRevealedSelection();
-    }
</del><ins>+    // We always need to notify the client on iOS to make sure the selection is redrawn,
+    // even during composition to support phrase boundary gesture.
+    notifyRevealedSelection();
</ins><span class="cx"> #elif PLATFORM(EFL) || PLATFORM(GTK)
</span><span class="cx">     m_pageClient.updateTextInputState();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -625,6 +625,12 @@
</span><span class="cx">     return _positionInformation.isSelectable;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)pointIsNearMarkedText:(CGPoint)point
+{
+    [self ensurePositionInformationIsUpToDate:point];
+    return _positionInformation.isNearMarkedText;
+}
+
</ins><span class="cx"> - (BOOL)pointIsInAssistedNode:(CGPoint)point
</span><span class="cx"> {
</span><span class="cx">     [self ensurePositionInformationIsUpToDate:point];
</span><span class="lines">@@ -1066,6 +1072,8 @@
</span><span class="cx">         return GestureType::TapOnLinkWithGesture;
</span><span class="cx">     case UIWKGestureMakeWebSelection:
</span><span class="cx">         return GestureType::MakeWebSelection;
</span><ins>+    case UIWKGesturePhraseBoundary:
+        return GestureType::PhraseBoundary;
</ins><span class="cx">     }
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return GestureType::Loupe;
</span><span class="lines">@@ -1102,6 +1110,8 @@
</span><span class="cx">         return UIWKGestureTapOnLinkWithGesture;
</span><span class="cx">     case GestureType::MakeWebSelection:
</span><span class="cx">         return UIWKGestureMakeWebSelection;
</span><ins>+    case GestureType::PhraseBoundary:
+        return UIWKGesturePhraseBoundary;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="tagsSafari538282SourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: tags/Safari-538.28.2/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (167118 => 167119)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-538.28.2/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-04-11 09:17:51 UTC (rev 167118)
+++ tags/Safari-538.28.2/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-04-11 09:23:01 UTC (rev 167119)
</span><span class="lines">@@ -537,6 +537,23 @@
</span><span class="cx">     SelectionFlags flags = None;
</span><span class="cx">     GestureRecognizerState wkGestureState = static_cast&lt;GestureRecognizerState&gt;(gestureState);
</span><span class="cx">     switch (static_cast&lt;GestureType&gt;(gestureType)) {
</span><ins>+    case GestureType::PhraseBoundary:
+    {
+        if (!frame.editor().hasComposition())
+            break;
+        RefPtr&lt;Range&gt; markedRange = frame.editor().compositionRange();
+        if (position &lt; markedRange-&gt;startPosition())
+            position = markedRange-&gt;startPosition();
+        if (position &gt; markedRange-&gt;endPosition())
+            position = markedRange-&gt;endPosition();
+        if (wkGestureState != GestureRecognizerState::Began)
+            flags = distanceBetweenPositions(markedRange-&gt;startPosition(), frame.selection().selection().start()) != distanceBetweenPositions(markedRange-&gt;startPosition(), position) ? PhraseBoundaryChanged : None;
+        else
+            flags = PhraseBoundaryChanged;
+        range = Range::create(*frame.document(), position, position);
+    }
+        break;
+
</ins><span class="cx">     case GestureType::OneFingerTap:
</span><span class="cx">     {
</span><span class="cx">         VisiblePosition result;
</span><span class="lines">@@ -1468,6 +1485,29 @@
</span><span class="cx"> 
</span><span class="cx">     info.point = point;
</span><span class="cx">     info.nodeAtPositionIsAssistedNode = (hitNode == m_assistedNode);
</span><ins>+    if (m_assistedNode) {
+        Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
+        if (frame.editor().hasComposition()) {
+            const uint32_t kHitAreaWidth = 66;
+            const uint32_t kHitAreaHeight = 66;
+            FrameView&amp; view = *frame.view();
+            IntPoint adjustedPoint(view.rootViewToContents(point));
+            IntPoint constrainedPoint = m_assistedNode ? constrainPoint(adjustedPoint, &amp;frame, m_assistedNode.get()) : adjustedPoint;
+            VisiblePosition position = frame.visiblePositionForPoint(constrainedPoint);
+
+            RefPtr&lt;Range&gt; compositionRange = frame.editor().compositionRange();
+            if (position &lt; compositionRange-&gt;startPosition())
+                position = compositionRange-&gt;startPosition();
+            else if (position &gt; compositionRange-&gt;endPosition())
+                position = compositionRange-&gt;endPosition();
+            IntRect caretRect = view.contentsToRootView(position.absoluteCaretBounds());
+            float deltaX = abs(caretRect.x() + (caretRect.width() / 2) - point.x());
+            float deltaYFromTheTop = abs(caretRect.y() - point.y());
+            float deltaYFromTheBottom = abs(caretRect.y() + caretRect.height() - point.y());
+
+            info.isNearMarkedText = !(deltaX &gt; kHitAreaWidth || deltaYFromTheTop &gt; kHitAreaHeight || deltaYFromTheBottom &gt; kHitAreaHeight);
+        }
+    }
</ins><span class="cx">     bool elementIsLinkOrImage = false;
</span><span class="cx">     if (hitNode) {
</span><span class="cx">         info.clickableElementName = hitNode-&gt;nodeName();
</span></span></pre>
</div>
</div>

</body>
</html>