<!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>[165572] 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/165572">165572</a></dd>
<dt>Author</dt> <dd>enrica@apple.com</dd>
<dt>Date</dt> <dd>2014-03-13 15:36:57 -0700 (Thu, 13 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS WebKit2] block selection should avoid large blocks.
https://bugs.webkit.org/show_bug.cgi?id=130208
&lt;rdar://problem/16251785&gt;

Reviewed by Benjamin Poulain.

When creating a block selection, we should discard blocks that
are larger than most of the visible portion of the document.
This prevents the accidental selection the entire document, which
is fairly common when tapping over empty areas.

* Shared/InteractionInformationAtPosition.cpp:
(WebKit::InteractionInformationAtPosition::encode):
(WebKit::InteractionInformationAtPosition::decode):
* Shared/InteractionInformationAtPosition.h: Removed selectionRects that was not really needed and
added isSelectable to indicate whether the selection can start.
(WebKit::InteractionInformationAtPosition::InteractionInformationAtPosition):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView hasSelectablePositionAtPoint:]): Now uses isSelectable.
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPositionInformation): Takes into account the userSelect property
to figure out if the element can be selected and discards blocks that are
larger than 97% of the visible area of the document.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedInteractionInformationAtPositioncpp">trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedInteractionInformationAtPositionh">trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</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 (165571 => 165572)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-03-13 22:18:50 UTC (rev 165571)
+++ trunk/Source/WebKit2/ChangeLog        2014-03-13 22:36:57 UTC (rev 165572)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2014-03-13  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        [iOS WebKit2] block selection should avoid large blocks.
+        https://bugs.webkit.org/show_bug.cgi?id=130208
+        &lt;rdar://problem/16251785&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        When creating a block selection, we should discard blocks that
+        are larger than most of the visible portion of the document.
+        This prevents the accidental selection the entire document, which
+        is fairly common when tapping over empty areas.
+
+        * Shared/InteractionInformationAtPosition.cpp:
+        (WebKit::InteractionInformationAtPosition::encode):
+        (WebKit::InteractionInformationAtPosition::decode):
+        * Shared/InteractionInformationAtPosition.h: Removed selectionRects that was not really needed and
+        added isSelectable to indicate whether the selection can start.
+        (WebKit::InteractionInformationAtPosition::InteractionInformationAtPosition):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView hasSelectablePositionAtPoint:]): Now uses isSelectable.
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getPositionInformation): Takes into account the userSelect property
+        to figure out if the element can be selected and discards blocks that are
+        larger than 97% of the visible area of the document.
+
</ins><span class="cx"> 2014-03-13  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename WKVisitedLinkProvider to _WKVisitedLinkProvider and make it private
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp (165571 => 165572)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-03-13 22:18:50 UTC (rev 165571)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-03-13 22:36:57 UTC (rev 165572)
</span><span class="lines">@@ -36,10 +36,10 @@
</span><span class="cx"> {
</span><span class="cx">     encoder &lt;&lt; point;
</span><span class="cx">     encoder &lt;&lt; nodeAtPositionIsAssistedNode;
</span><ins>+    encoder &lt;&lt; isSelectable;
</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><del>-    encoder &lt;&lt; selectionRects;
</del><span class="cx">     encoder &lt;&lt; bounds;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -51,6 +51,9 @@
</span><span class="cx">     if (!decoder.decode(result.nodeAtPositionIsAssistedNode))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.isSelectable))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.clickableElementName))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -60,9 +63,6 @@
</span><span class="cx">     if (!decoder.decode(result.title))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (!decoder.decode(result.selectionRects))
-        return false;
-
</del><span class="cx">     if (!decoder.decode(result.bounds))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h (165571 => 165572)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-03-13 22:18:50 UTC (rev 165571)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-03-13 22:36:57 UTC (rev 165572)
</span><span class="lines">@@ -37,15 +37,16 @@
</span><span class="cx"> struct InteractionInformationAtPosition {
</span><span class="cx">     InteractionInformationAtPosition()
</span><span class="cx">         : nodeAtPositionIsAssistedNode(false)
</span><ins>+        , isSelectable(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><ins>+    bool isSelectable;
</ins><span class="cx">     String clickableElementName;
</span><span class="cx">     String url;
</span><span class="cx">     String title;
</span><del>-    Vector&lt;WebCore::SelectionRect&gt; selectionRects;
</del><span class="cx">     WebCore::IntRect bounds;
</span><span class="cx"> 
</span><span class="cx">     void encode(IPC::ArgumentEncoder&amp;) const;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (165571 => 165572)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-03-13 22:18:50 UTC (rev 165571)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-03-13 22:36:57 UTC (rev 165572)
</span><span class="lines">@@ -574,9 +574,7 @@
</span><span class="cx"> - (BOOL)hasSelectablePositionAtPoint:(CGPoint)point
</span><span class="cx"> {
</span><span class="cx">     [self ensurePositionInformationIsUpToDate:point];
</span><del>-    // FIXME: This check needs to be extended to include other elements.
-    // FIXME: We need to reject positions that will lead to a very large selection.
-    return _positionInformation.clickableElementName != &quot;IMG&quot; &amp;&amp; _positionInformation.clickableElementName != &quot;A&quot; &amp;&amp; !_positionInformation.selectionRects.isEmpty();
</del><ins>+    return _positionInformation.isSelectable;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)pointIsInAssistedNode:(CGPoint)point
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (165571 => 165572)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-03-13 22:18:50 UTC (rev 165571)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-03-13 22:36:57 UTC (rev 165572)
</span><span class="lines">@@ -1491,9 +1491,12 @@
</span><span class="cx">         hitNode = result.innerNode();
</span><span class="cx">         // Hit test could return HTMLHtmlElement that has no renderer, if the body is smaller than the document.
</span><span class="cx">         if (hitNode &amp;&amp; hitNode-&gt;renderer()) {
</span><ins>+            RenderObject* renderer = hitNode-&gt;renderer();
</ins><span class="cx">             m_page-&gt;focusController().setFocusedFrame(result.innerNodeFrame());
</span><del>-            info.selectionRects.append(SelectionRect(hitNode-&gt;renderer()-&gt;absoluteBoundingBoxRect(true), true, 0));
-            info.bounds = hitNode-&gt;renderer()-&gt;absoluteBoundingBoxRect();
</del><ins>+            info.bounds = renderer-&gt;absoluteBoundingBoxRect(true);
+            // We don't want to select blocks that are larger than 97% of the visible area of the document.
+            const static CGFloat factor = 0.97;
+            info.isSelectable = renderer-&gt;style().userSelect() != SELECT_NONE &amp;&amp; info.bounds.height() &lt; result.innerNodeFrame()-&gt;view()-&gt;unobscuredContentRect().height() * factor;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>