<!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>[186849] trunk/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/186849">186849</a></dd>
<dt>Author</dt> <dd>enrica@apple.com</dd>
<dt>Date</dt> <dd>2015-07-15 10:52:11 -0700 (Wed, 15 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Add support for updateSelectionWithExtentPoint:withBoundary.
https://bugs.webkit.org/show_bug.cgi?id=146951
rdar://problem/20864286

Reviewed by Tim Horton.

Add implementation for new method used by text selection
engine on iOS. The new function modifies the selection near the given point
and snaps it at the boundary of the specified granularity.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView updateSelectionWithExtentPoint:completionHandler:]):
(-[WKContentView updateSelectionWithExtentPoint:withBoundary:completionHandler:]):
(-[WKContentView _characterBeforeCaretSelection]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::updateSelectionWithExtentPoint):
(WebKit::WebPageProxy::updateSelectionWithExtentPointAndBoundary):
(WebKit::WebPageProxy::requestDictationContext):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::rangeForGranularityAtPoint):
(WebKit::WebPage::selectTextWithGranularityAtPoint):
(WebKit::WebPage::updateSelectionWithExtentPointAndBoundary):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/ChangeLog        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2015-07-14  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        [iOS] Add support for updateSelectionWithExtentPoint:withBoundary.
+        https://bugs.webkit.org/show_bug.cgi?id=146951
+        rdar://problem/20864286
+
+        Reviewed by Tim Horton.
+
+        Add implementation for new method used by text selection
+        engine on iOS. The new function modifies the selection near the given point
+        and snaps it at the boundary of the specified granularity.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView updateSelectionWithExtentPoint:completionHandler:]):
+        (-[WKContentView updateSelectionWithExtentPoint:withBoundary:completionHandler:]):
+        (-[WKContentView _characterBeforeCaretSelection]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::updateSelectionWithExtentPoint):
+        (WebKit::WebPageProxy::updateSelectionWithExtentPointAndBoundary):
+        (WebKit::WebPageProxy::requestDictationContext):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::rangeForGranularityAtPoint):
+        (WebKit::WebPage::selectTextWithGranularityAtPoint):
+        (WebKit::WebPage::updateSelectionWithExtentPointAndBoundary):
+
</ins><span class="cx"> 2015-07-15  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Linux] SeccompBrokerClient should cache arbitrary file descriptors
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -488,6 +488,7 @@
</span><span class="cx">     void moveSelectionAtBoundaryWithDirection(WebCore::TextGranularity, WebCore::SelectionDirection, std::function&lt;void(CallbackBase::Error)&gt;);
</span><span class="cx">     void beginSelectionInDirection(WebCore::SelectionDirection, std::function&lt;void (uint64_t, CallbackBase::Error)&gt;);
</span><span class="cx">     void updateSelectionWithExtentPoint(const WebCore::IntPoint, std::function&lt;void (uint64_t, CallbackBase::Error)&gt;);
</span><ins>+    void updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint, WebCore::TextGranularity, std::function&lt;void(uint64_t, CallbackBase::Error)&gt;);
</ins><span class="cx">     void requestAutocorrectionData(const String&amp; textForAutocorrection, std::function&lt;void (const Vector&lt;WebCore::FloatRect&gt;&amp;, const String&amp;, double, uint64_t, CallbackBase::Error)&gt;);
</span><span class="cx">     void applyAutocorrection(const String&amp; correction, const String&amp; originalText, std::function&lt;void (const String&amp;, CallbackBase::Error)&gt;);
</span><span class="cx">     bool applyAutocorrection(const String&amp; correction, const String&amp; originalText);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -2043,6 +2043,16 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)updateSelectionWithExtentPoint:(CGPoint)point withBoundary:(UITextGranularity)granularity completionHandler:(void (^)(BOOL selectionEndIsMoving))completionHandler
+{
+    UIWKSelectionWithDirectionCompletionHandler selectionHandler = [completionHandler copy];
+    
+    _page-&gt;updateSelectionWithExtentPointAndBoundary(WebCore::IntPoint(point), toWKTextGranularity(granularity), [selectionHandler](bool endIsMoving, WebKit::CallbackBase::Error error) {
+        selectionHandler(endIsMoving);
+        [selectionHandler release];
+    });
+}
+
</ins><span class="cx"> - (UTF32Char)_characterBeforeCaretSelection
</span><span class="cx"> {
</span><span class="cx">     return _page-&gt;editorState().postLayoutData().characterBeforeSelection;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -496,6 +496,18 @@
</span><span class="cx">     
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint point, WebCore::TextGranularity granularity, std::function&lt;void(uint64_t, CallbackBase::Error)&gt; callbackFunction)
+{
+    if (!isValid()) {
+        callbackFunction(0, CallbackBase::Error::Unknown);
+        return;
+    }
+    
+    uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process-&gt;throttler().backgroundActivityToken());
+    m_process-&gt;send(Messages::WebPage::UpdateSelectionWithExtentPointAndBoundary(point, granularity, callbackID), m_pageID);
+    
+}
+
</ins><span class="cx"> void WebPageProxy::requestDictationContext(std::function&lt;void (const String&amp;, const String&amp;, const String&amp;, CallbackBase::Error)&gt; callbackFunction)
</span><span class="cx"> {
</span><span class="cx">     if (!isValid()) {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -509,6 +509,7 @@
</span><span class="cx">     void selectPositionAtPoint(const WebCore::IntPoint&amp;, uint64_t callbackID);
</span><span class="cx">     void beginSelectionInDirection(uint32_t direction, uint64_t callbackID);
</span><span class="cx">     void updateSelectionWithExtentPoint(const WebCore::IntPoint&amp;, uint64_t callbackID);
</span><ins>+    void updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint&amp;, uint32_t granularity, uint64_t callbackID);
</ins><span class="cx"> 
</span><span class="cx">     void elementDidFocus(WebCore::Node*);
</span><span class="cx">     void elementDidBlur(WebCore::Node*);
</span><span class="lines">@@ -929,6 +930,7 @@
</span><span class="cx">     void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*);
</span><span class="cx">     void resetTextAutosizingBeforeLayoutIfNeeded(const WebCore::FloatSize&amp; oldSize, const WebCore::FloatSize&amp; newSize);
</span><span class="cx">     WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(const WebCore::Frame&amp;, const WebCore::IntPoint&amp;);
</span><ins>+    PassRefPtr&lt;WebCore::Range&gt; rangeForGranularityAtPoint(const WebCore::Frame&amp;, const WebCore::IntPoint&amp;, uint32_t granularity);
</ins><span class="cx">     void volatilityTimerFired();
</span><span class="cx"> #endif
</span><span class="cx"> #if !PLATFORM(COCOA)
</span><span class="lines">@@ -1346,6 +1348,7 @@
</span><span class="cx">     WebCore::FloatSize m_screenSize;
</span><span class="cx">     WebCore::FloatSize m_availableScreenSize;
</span><span class="cx">     RefPtr&lt;WebCore::Range&gt; m_currentBlockSelection;
</span><ins>+    RefPtr&lt;WebCore::Range&gt; m_initialSelection;
</ins><span class="cx">     WebCore::IntSize m_blockSelectionDesiredSize;
</span><span class="cx">     WebCore::FloatSize m_maximumUnobscuredSize;
</span><span class="cx">     int32_t m_deviceOrientation;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx">     SelectPositionAtPoint(WebCore::IntPoint point, uint64_t callbackID)
</span><span class="cx">     BeginSelectionInDirection(uint32_t direction, uint64_t callbackID)
</span><span class="cx">     UpdateSelectionWithExtentPoint(WebCore::IntPoint point, uint64_t callbackID)
</span><ins>+    UpdateSelectionWithExtentPointAndBoundary(WebCore::IntPoint point, uint32_t granularity, uint64_t callbackID)
</ins><span class="cx">     RequestDictationContext(uint64_t callbackID)
</span><span class="cx">     ReplaceDictatedText(String oldText, String newText)
</span><span class="cx">     ReplaceSelectedText(String oldText, String newText)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (186848 => 186849)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-07-15 17:42:06 UTC (rev 186848)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-07-15 17:52:11 UTC (rev 186849)
</span><span class="lines">@@ -1734,9 +1734,8 @@
</span><span class="cx">     send(Messages::WebPageProxy::VoidCallback(callbackID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::selectTextWithGranularityAtPoint(const WebCore::IntPoint&amp; point, uint32_t granularity, uint64_t callbackID)
</del><ins>+PassRefPtr&lt;Range&gt; WebPage::rangeForGranularityAtPoint(const Frame&amp; frame, const WebCore::IntPoint&amp; point, uint32_t granularity)
</ins><span class="cx"> {
</span><del>-    const Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</del><span class="cx">     VisiblePosition position = visiblePositionInFocusedNodeForPoint(frame, point);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Range&gt; range;
</span><span class="lines">@@ -1756,8 +1755,17 @@
</span><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+    return range;
+}
+
+void WebPage::selectTextWithGranularityAtPoint(const WebCore::IntPoint&amp; point, uint32_t granularity, uint64_t callbackID)
+{
+    const Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
+    RefPtr&lt;Range&gt; range = rangeForGranularityAtPoint(frame, point, granularity);
+
</ins><span class="cx">     if (range)
</span><span class="cx">         frame.selection().setSelectedRange(range.get(), UPSTREAM, true);
</span><ins>+    m_initialSelection = range;
</ins><span class="cx">     send(Messages::WebPageProxy::VoidCallback(callbackID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1766,7 +1774,36 @@
</span><span class="cx">     m_selectionAnchor = (static_cast&lt;SelectionDirection&gt;(direction) == DirectionLeft) ? Start : End;
</span><span class="cx">     send(Messages::WebPageProxy::UnsignedCallback(m_selectionAnchor == Start, callbackID));
</span><span class="cx"> }
</span><ins>+
+void WebPage::updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint&amp; point, uint32_t granularity, uint64_t callbackID)
+{
+    const Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
+    VisiblePosition position = visiblePositionInFocusedNodeForPoint(frame, point);
+    RefPtr&lt;Range&gt; newRange = rangeForGranularityAtPoint(frame, point, granularity);
</ins><span class="cx">     
</span><ins>+    if (position.isNull() || !m_initialSelection || !newRange) {
+        send(Messages::WebPageProxy::UnsignedCallback(false, callbackID));
+        return;
+    }
+    
+    RefPtr&lt;Range&gt; range;
+    VisiblePosition selectionStart = m_initialSelection-&gt;startPosition();
+    VisiblePosition selectionEnd = m_initialSelection-&gt;endPosition();
+
+    if (position &gt; m_initialSelection-&gt;endPosition())
+        selectionEnd = newRange-&gt;endPosition();
+    else if (position &lt; m_initialSelection-&gt;startPosition())
+        selectionStart = newRange-&gt;startPosition();
+    
+    if (selectionStart.isNotNull() &amp;&amp; selectionEnd.isNotNull())
+        range = Range::create(*frame.document(), selectionStart, selectionEnd);
+    
+    if (range)
+        frame.selection().setSelectedRange(range.get(), UPSTREAM, true);
+    
+    send(Messages::WebPageProxy::UnsignedCallback(selectionStart == m_initialSelection-&gt;startPosition(), callbackID));
+}
+
</ins><span class="cx"> void WebPage::updateSelectionWithExtentPoint(const WebCore::IntPoint&amp; point, uint64_t callbackID)
</span><span class="cx"> {
</span><span class="cx">     const Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</span></span></pre>
</div>
</div>

</body>
</html>