<!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>[186916] trunk/Source</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/186916">186916</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2015-07-16 16:14:34 -0700 (Thu, 16 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add shrink-wrapped link highlights
https://bugs.webkit.org/show_bug.cgi?id=147021
&lt;rdar://problem/21643094&gt;

Reviewed by Enrica Casucci.

* Shared/InteractionInformationAtPosition.cpp:
(WebKit::InteractionInformationAtPosition::encode):
(WebKit::InteractionInformationAtPosition::decode):
* Shared/InteractionInformationAtPosition.h:
Add a TextIndicator to InteractionInformationAtPosition.
Make use of some new C++ features.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView willPresentPreviewViewController:forPosition:inSourceView:]):
(-[WKContentView didDismissPreviewViewController:committing:]):
Make use of the TextIndicator (if we have one) to show a shrink-wrapped
snapshot of the link.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPositionInformation):
Build a TextIndicator for the link if possible.

* WebCore.xcodeproj/project.pbxproj:
* page/TextIndicator.cpp:
(WebCore::TextIndicator::createWithRange):
(WebCore::TextIndicator::createWithSelectionInFrame):
* page/TextIndicator.h:
Add a margin parameter to TextIndicator; this inflates each text rect
by the given amount.

Use snapshotFrameRect instead of snapshotSelection because we really
want an image that exactly fits textBoundingRectInDocumentCoordinates,
and snapshotSelection comes up with selection rects in different ways,
especially on iOS (where it comes up with nothing!).

For now, avoid forcing black text or painting only the selection on iOS.
Eventually, we should have TextIndicator options for these things that
are then respected at the presentation layer.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorepageTextIndicatorcpp">trunk/Source/WebCore/page/TextIndicator.cpp</a></li>
<li><a href="#trunkSourceWebCorepageTextIndicatorh">trunk/Source/WebCore/page/TextIndicator.h</a></li>
<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="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionh">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.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="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebCore/ChangeLog        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-07-16  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Add shrink-wrapped link highlights
+        https://bugs.webkit.org/show_bug.cgi?id=147021
+        &lt;rdar://problem/21643094&gt;
+
+        Reviewed by Enrica Casucci.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/TextIndicator.cpp:
+        (WebCore::TextIndicator::createWithRange):
+        (WebCore::TextIndicator::createWithSelectionInFrame):
+        * page/TextIndicator.h:
+        Add a margin parameter to TextIndicator; this inflates each text rect
+        by the given amount.
+
+        Use snapshotFrameRect instead of snapshotSelection because we really
+        want an image that exactly fits textBoundingRectInDocumentCoordinates,
+        and snapshotSelection comes up with selection rects in different ways,
+        especially on iOS (where it comes up with nothing!).
+
+        For now, avoid forcing black text or painting only the selection on iOS.
+        Eventually, we should have TextIndicator options for these things that
+        are then respected at the presentation layer.
+
</ins><span class="cx"> 2015-07-16  Matt Rajca  &lt;mrajca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Media Session: remove plumbing for delivering start/end-of-interruption events
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -1127,7 +1127,7 @@
</span><span class="cx">                 2D4F96F81A1ECC240098BF88 /* TextIndicatorWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D4F96F41A1ECC240098BF88 /* TextIndicatorWindow.mm */; };
</span><span class="cx">                 2D5002F81B56D7810020AAF7 /* DOMPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D5002F71B56D7810020AAF7 /* DOMPath.cpp */; };
</span><span class="cx">                 2D5002FB1B56D7990020AAF7 /* PathUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D5002F91B56D7990020AAF7 /* PathUtilities.cpp */; };
</span><del>-                2D5002FC1B56D7990020AAF7 /* PathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5002FA1B56D7990020AAF7 /* PathUtilities.h */; };
</del><ins>+                2D5002FC1B56D7990020AAF7 /* PathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5002FA1B56D7990020AAF7 /* PathUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 2D58D8551A15F65F00A5F726 /* DataDetection.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D58D8531A15F65F00A5F726 /* DataDetection.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 2D58D8561A15F65F00A5F726 /* DataDetection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D58D8541A15F65F00A5F726 /* DataDetection.mm */; };
</span><span class="cx">                 2D59F1BF1A0044C6001F3D29 /* DataDetectorsSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D59F1BE1A0044C6001F3D29 /* DataDetectorsSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span></span></pre></div>
<a id="trunkSourceWebCorepageTextIndicatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/TextIndicator.cpp (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/TextIndicator.cpp        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebCore/page/TextIndicator.cpp        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">     return adoptRef(*new TextIndicator(data));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;TextIndicator&gt; TextIndicator::createWithRange(const Range&amp; range, TextIndicatorPresentationTransition presentationTransition)
</del><ins>+RefPtr&lt;TextIndicator&gt; TextIndicator::createWithRange(const Range&amp; range, TextIndicatorPresentationTransition presentationTransition, unsigned margin)
</ins><span class="cx"> {
</span><span class="cx">     Frame* frame = range.startContainer()-&gt;document().frame();
</span><span class="cx"> 
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">     VisibleSelection oldSelection = frame-&gt;selection().selection();
</span><span class="cx">     frame-&gt;selection().setSelection(range);
</span><span class="cx"> 
</span><del>-    RefPtr&lt;TextIndicator&gt; indicator = TextIndicator::createWithSelectionInFrame(*frame, presentationTransition);
</del><ins>+    RefPtr&lt;TextIndicator&gt; indicator = TextIndicator::createWithSelectionInFrame(*frame, presentationTransition, margin);
</ins><span class="cx"> 
</span><span class="cx">     frame-&gt;selection().setSelection(oldSelection);
</span><span class="cx"> 
</span><span class="lines">@@ -90,24 +90,8 @@
</span><span class="cx">     return snapshot-&gt;copyImage(CopyBackingStore, Unscaled);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;TextIndicator&gt; TextIndicator::createWithSelectionInFrame(Frame&amp; frame, TextIndicatorPresentationTransition presentationTransition)
</del><ins>+RefPtr&lt;TextIndicator&gt; TextIndicator::createWithSelectionInFrame(Frame&amp; frame, TextIndicatorPresentationTransition presentationTransition, unsigned margin)
</ins><span class="cx"> {
</span><del>-    IntRect selectionRect = enclosingIntRect(frame.selection().selectionBounds());
-    std::unique_ptr&lt;ImageBuffer&gt; indicatorBuffer = snapshotSelection(frame, SnapshotOptionsForceBlackText);
-    if (!indicatorBuffer)
-        return nullptr;
-    RefPtr&lt;Image&gt; indicatorBitmap = indicatorBuffer-&gt;copyImage(CopyBackingStore, Unscaled);
-    if (!indicatorBitmap)
-        return nullptr;
-
-    RefPtr&lt;Image&gt; indicatorBitmapWithHighlight;
-    if (presentationTransition == TextIndicatorPresentationTransition::BounceAndCrossfade)
-        indicatorBitmapWithHighlight = snapshotSelectionWithHighlight(frame);
-
-    // Store the selection rect in window coordinates, to be used subsequently
-    // to determine if the indicator and selection still precisely overlap.
-    IntRect selectionRectInRootViewCoordinates = frame.view()-&gt;contentsToRootView(selectionRect);
-
</del><span class="cx">     Vector&lt;FloatRect&gt; textRects;
</span><span class="cx">     frame.selection().getClippedVisibleTextRectangles(textRects);
</span><span class="cx"> 
</span><span class="lines">@@ -115,9 +99,15 @@
</span><span class="cx">     // rect when the selection spans multiple lines; the indicator doesn't actually
</span><span class="cx">     // care where the selection highlight goes, just where the text actually is.
</span><span class="cx">     FloatRect textBoundingRectInRootViewCoordinates;
</span><ins>+    FloatRect textBoundingRectInDocumentCoordinates;
</ins><span class="cx">     Vector&lt;FloatRect&gt; textRectsInRootViewCoordinates;
</span><span class="cx">     for (const FloatRect&amp; textRect : textRects) {
</span><del>-        FloatRect textRectInRootViewCoordinates = frame.view()-&gt;contentsToRootView(enclosingIntRect(textRect));
</del><ins>+        FloatRect textRectInDocumentCoordinatesIncludingMargin = textRect;
+        textRectInDocumentCoordinatesIncludingMargin.inflate(margin);
+
+        textBoundingRectInDocumentCoordinates.unite(textRectInDocumentCoordinatesIncludingMargin);
+
+        FloatRect textRectInRootViewCoordinates = frame.view()-&gt;contentsToRootView(enclosingIntRect(textRectInDocumentCoordinatesIncludingMargin));
</ins><span class="cx">         textRectsInRootViewCoordinates.append(textRectInRootViewCoordinates);
</span><span class="cx">         textBoundingRectInRootViewCoordinates.unite(textRectInRootViewCoordinates);
</span><span class="cx">     }
</span><span class="lines">@@ -128,8 +118,29 @@
</span><span class="cx">         textRectsInBoundingRectCoordinates.append(rect);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // FIXME: We should have TextIndicator options instead of this being platform-specific.
+#if PLATFORM(IOS)
+    SnapshotOptions snapshotOptions = SnapshotOptionsNone;
+#else
+    SnapshotOptions snapshotOptions = SnapshotOptionsForceBlackText | SnapshotOptionsPaintSelectionOnly;
+#endif
+
+    std::unique_ptr&lt;ImageBuffer&gt; indicatorBuffer = snapshotFrameRect(frame, enclosingIntRect(textBoundingRectInDocumentCoordinates), snapshotOptions);
+    if (!indicatorBuffer)
+        return nullptr;
+    RefPtr&lt;Image&gt; indicatorBitmap = indicatorBuffer-&gt;copyImage(CopyBackingStore, Unscaled);
+    if (!indicatorBitmap)
+        return nullptr;
+
+    RefPtr&lt;Image&gt; indicatorBitmapWithHighlight;
+    if (presentationTransition == TextIndicatorPresentationTransition::BounceAndCrossfade)
+        indicatorBitmapWithHighlight = snapshotSelectionWithHighlight(frame);
+
</ins><span class="cx">     TextIndicatorData data;
</span><del>-    data.selectionRectInRootViewCoordinates = selectionRectInRootViewCoordinates;
</del><ins>+
+    // Store the selection rect in window coordinates, to be used subsequently
+    // to determine if the indicator and selection still precisely overlap.
+    data.selectionRectInRootViewCoordinates = frame.view()-&gt;contentsToRootView(enclosingIntRect(frame.selection().selectionBounds()));
</ins><span class="cx">     data.textBoundingRectInRootViewCoordinates = textBoundingRectInRootViewCoordinates;
</span><span class="cx">     data.textRectsInBoundingRectCoordinates = textRectsInBoundingRectCoordinates;
</span><span class="cx">     data.contentImageScaleFactor = frame.page()-&gt;deviceScaleFactor();
</span></span></pre></div>
<a id="trunkSourceWebCorepageTextIndicatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/TextIndicator.h (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/TextIndicator.h        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebCore/page/TextIndicator.h        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -82,8 +82,8 @@
</span><span class="cx"> class TextIndicator : public RefCounted&lt;TextIndicator&gt; {
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT static Ref&lt;TextIndicator&gt; create(const TextIndicatorData&amp;);
</span><del>-    WEBCORE_EXPORT static RefPtr&lt;TextIndicator&gt; createWithSelectionInFrame(Frame&amp;, TextIndicatorPresentationTransition);
-    WEBCORE_EXPORT static RefPtr&lt;TextIndicator&gt; createWithRange(const Range&amp;, TextIndicatorPresentationTransition);
</del><ins>+    WEBCORE_EXPORT static RefPtr&lt;TextIndicator&gt; createWithSelectionInFrame(Frame&amp;, TextIndicatorPresentationTransition, unsigned margin = 0);
+    WEBCORE_EXPORT static RefPtr&lt;TextIndicator&gt; createWithRange(const Range&amp;, TextIndicatorPresentationTransition, unsigned margin = 0);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT ~TextIndicator();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/ChangeLog        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2015-07-16  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Add shrink-wrapped link highlights
+        https://bugs.webkit.org/show_bug.cgi?id=147021
+        &lt;rdar://problem/21643094&gt;
+
+        Reviewed by Enrica Casucci.
+
+        * Shared/InteractionInformationAtPosition.cpp:
+        (WebKit::InteractionInformationAtPosition::encode):
+        (WebKit::InteractionInformationAtPosition::decode):
+        * Shared/InteractionInformationAtPosition.h:
+        Add a TextIndicator to InteractionInformationAtPosition.
+        Make use of some new C++ features.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView willPresentPreviewViewController:forPosition:inSourceView:]):
+        (-[WKContentView didDismissPreviewViewController:committing:]):
+        Make use of the TextIndicator (if we have one) to show a shrink-wrapped
+        snapshot of the link.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getPositionInformation):
+        Build a TextIndicator for the link if possible.
+
</ins><span class="cx"> 2015-07-16  Matt Rajca  &lt;mrajca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Media Session: remove plumbing for delivering start/end-of-interruption events
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">     encoder &lt;&lt; imageURL;
</span><span class="cx">     encoder &lt;&lt; title;
</span><span class="cx">     encoder &lt;&lt; bounds;
</span><ins>+    encoder &lt;&lt; linkIndicator;
</ins><span class="cx"> 
</span><span class="cx">     ShareableBitmap::Handle handle;
</span><span class="cx">     if (image)
</span><span class="lines">@@ -83,6 +84,9 @@
</span><span class="cx">     if (!decoder.decode(result.bounds))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.linkIndicator))
+        return false;
+
</ins><span class="cx">     ShareableBitmap::Handle handle;
</span><span class="cx">     if (!decoder.decode(handle))
</span><span class="cx">         return false;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -26,32 +26,23 @@
</span><span class="cx"> #ifndef InteractionInformationAtPosition_h
</span><span class="cx"> #define InteractionInformationAtPosition_h
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+
</ins><span class="cx"> #include &quot;ArgumentCoders.h&quot;
</span><span class="cx"> #include &quot;ShareableBitmap.h&quot;
</span><span class="cx"> #include &lt;WebCore/IntPoint.h&gt;
</span><ins>+#include &lt;WebCore/SelectionRect.h&gt;
+#include &lt;WebCore/TextIndicator.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
-#include &lt;WebCore/SelectionRect.h&gt;
-#endif
-
</del><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
</del><span class="cx"> struct InteractionInformationAtPosition {
</span><del>-    InteractionInformationAtPosition()
-        : nodeAtPositionIsAssistedNode(false)
-        , isSelectable(false)
-        , isNearMarkedText(false)
-        , touchCalloutEnabled(true)
-    {
-    }
-
</del><span class="cx">     WebCore::IntPoint point;
</span><del>-    bool nodeAtPositionIsAssistedNode;
-    bool isSelectable;
-    bool isNearMarkedText;
-    bool touchCalloutEnabled;
</del><ins>+    bool nodeAtPositionIsAssistedNode { false };
+    bool isSelectable { false };
+    bool isNearMarkedText { false };
+    bool touchCalloutEnabled { true };
</ins><span class="cx">     String clickableElementName;
</span><span class="cx">     String url;
</span><span class="cx">     String imageURL;
</span><span class="lines">@@ -59,11 +50,14 @@
</span><span class="cx">     WebCore::IntRect bounds;
</span><span class="cx">     RefPtr&lt;ShareableBitmap&gt; image;
</span><span class="cx"> 
</span><ins>+    WebCore::TextIndicatorData linkIndicator;
+
</ins><span class="cx">     void encode(IPC::ArgumentEncoder&amp;) const;
</span><span class="cx">     static bool decode(IPC::ArgumentDecoder&amp;, InteractionInformationAtPosition&amp;);
</span><span class="cx"> };
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif // PLATFORM(IOS)
+
</ins><span class="cx"> #endif // InteractionInformationAtPosition_h
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -156,6 +156,8 @@
</span><span class="cx">     id &lt;UIViewControllerPreviewing&gt; _previewing;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    RetainPtr&lt;UIImageView&gt; _previewIndicatorView;
+
</ins><span class="cx">     BOOL _isEditable;
</span><span class="cx">     BOOL _showingTextStyleOptions;
</span><span class="cx">     BOOL _hasValidPositionInformation;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -62,8 +62,11 @@
</span><span class="cx"> #import &lt;WebCore/CoreGraphicsSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/FloatQuad.h&gt;
</span><span class="cx"> #import &lt;WebCore/Pasteboard.h&gt;
</span><ins>+#import &lt;WebCore/Path.h&gt;
+#import &lt;WebCore/PathUtilities.h&gt;
</ins><span class="cx"> #import &lt;WebCore/Scrollbar.h&gt;
</span><span class="cx"> #import &lt;WebCore/SoftLinking.h&gt;
</span><ins>+#import &lt;WebCore/TextIndicator.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebEvent.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebSelectionRect.h&gt; // FIXME: WK2 should not include WebKit headers!
</span><span class="cx"> #import &lt;WebKitSystemInterfaceIOS.h&gt;
</span><span class="lines">@@ -3315,7 +3318,31 @@
</span><span class="cx">     [self _removeDefaultGestureRecognizers];
</span><span class="cx"> 
</span><span class="cx">     [self _cancelInteraction];
</span><del>-    [[viewController presentationController] setSourceRect:_positionInformation.bounds];
</del><ins>+
+    [_previewIndicatorView removeFromSuperview];
+
+    RefPtr&lt;Image&gt; image = _positionInformation.linkIndicator.contentImage;
+    if (!image) {
+        [[viewController presentationController] setSourceRect:_positionInformation.bounds];
+        [[viewController presentationController] setSourceView:self];
+        return;
+    }
+
+    RetainPtr&lt;UIImage&gt; indicatorImage = adoptNS([[UIImage alloc] initWithCGImage:image-&gt;getCGImageRef()]);
+    _previewIndicatorView = adoptNS([[UIImageView alloc] initWithImage:indicatorImage.get()]);
+
+    float deviceScaleFactor = _page-&gt;deviceScaleFactor();
+    const float cornerRadiusInPoints = 5;
+    Path path = PathUtilities::pathWithShrinkWrappedRects(_positionInformation.linkIndicator.textRectsInBoundingRectCoordinates, cornerRadiusInPoints * deviceScaleFactor);
+    RetainPtr&lt;CAShapeLayer&gt; maskLayer = adoptNS([[CAShapeLayer alloc] init]);
+    [maskLayer setPath:path.ensurePlatformPath()];
+
+    [_previewIndicatorView layer].mask = maskLayer.get();
+    [_previewIndicatorView setFrame:_positionInformation.linkIndicator.textBoundingRectInRootViewCoordinates];
+    [self addSubview:_previewIndicatorView.get()];
+
+    [[viewController presentationController] setSourceRect:[_previewIndicatorView bounds]];
+    [[viewController presentationController] setSourceView:_previewIndicatorView.get()];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)didDismissPreviewViewController:(UIViewController *)viewController committing:(BOOL)committing
</span><span class="lines">@@ -3326,6 +3353,9 @@
</span><span class="cx">     id&lt;WKUIDelegatePrivate&gt; uiDelegate = static_cast&lt;id &lt;WKUIDelegatePrivate&gt;&gt;([_webView UIDelegate]);
</span><span class="cx">     if ([uiDelegate respondsToSelector:@selector(_webView:didDismissPreviewViewController:)])
</span><span class="cx">         [uiDelegate _webView:_webView didDismissPreviewViewController:viewController];
</span><ins>+
+    [_previewIndicatorView removeFromSuperview];
+    _previewIndicatorView = nil;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (186915 => 186916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-07-16 22:57:47 UTC (rev 186915)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-07-16 23:14:34 UTC (rev 186916)
</span><span class="lines">@@ -88,6 +88,7 @@
</span><span class="cx"> #import &lt;WebCore/RenderView.h&gt;
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/StyleProperties.h&gt;
</span><ins>+#import &lt;WebCore/TextIndicator.h&gt;
</ins><span class="cx"> #import &lt;WebCore/TextIterator.h&gt;
</span><span class="cx"> #import &lt;WebCore/VisibleUnits.h&gt;
</span><span class="cx"> #import &lt;WebCore/WKContentObservation.h&gt;
</span><span class="lines">@@ -2192,6 +2193,15 @@
</span><span class="cx">                     // Ensure that the image contains at most 600K pixels, so that it is not too big.
</span><span class="cx">                     if (RefPtr&lt;WebImage&gt; snapshot = snapshotNode(*element, SnapshotOptionsShareable, 600 * 1024))
</span><span class="cx">                         info.image = snapshot-&gt;bitmap();
</span><ins>+
+                    RefPtr&lt;Range&gt; linkRange = rangeOfContents(*linkElement);
+                    if (linkRange) {
+                        float deviceScaleFactor = corePage()-&gt;deviceScaleFactor();
+                        const float marginInPoints = 4;
+                        RefPtr&lt;TextIndicator&gt; textIndicator = TextIndicator::createWithRange(*linkRange, TextIndicatorPresentationTransition::FadeIn, marginInPoints * deviceScaleFactor);
+                        if (textIndicator)
+                            info.linkIndicator = textIndicator-&gt;data();
+                    }
</ins><span class="cx">                 } else if (element-&gt;renderer() &amp;&amp; element-&gt;renderer()-&gt;isRenderImage()) {
</span><span class="cx">                     auto&amp; renderImage = downcast&lt;RenderImage&gt;(*(element-&gt;renderer()));
</span><span class="cx">                     if (renderImage.cachedImage() &amp;&amp; !renderImage.cachedImage()-&gt;errorOccurred()) {
</span></span></pre>
</div>
</div>

</body>
</html>