<!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>[166818] 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/166818">166818</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2014-04-04 18:10:11 -0700 (Fri, 04 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Show DataDetector UI on scanned phone numbers.
&lt;rdar://problem/16379588&gt; and https://bugs.webkit.org/show_bug.cgi?id=131247

Reviewed by Tim Horton.

Source/WebCore:

Gather the ranges of the scanned telephone numbers and send them up to WK2:
* editing/Editor.cpp:
(WebCore::Editor::respondToChangedSelection):
(WebCore::Editor::scanSelectionForTelephoneNumbers):
(WebCore::Editor::scanRangeForTelephoneNumbers):
* editing/Editor.h:

Add client method to receive scanned telephone number ranges:
* page/EditorClient.h:
(WebCore::EditorClient::selectedTelephoneNumberRangesChanged):

Remove unneeded placeholder UI:
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintDocumentMarkers):
(WebCore::InlineTextBox::computeRectForReplacementMarker): Deleted.
(WebCore::InlineTextBox::paintCompositionUnderline): Deleted.
* rendering/InlineTextBox.h:
(WebCore::InlineTextBox::expansionBehavior): Deleted.

Source/WebKit2:

Add a new PageOverlay for telephone number UI, handle drawing the UI, and
handle mouse clicks on the button in that UI.

Even though clicks are detected, they aren’t acted upon yet.

* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::selectedTelephoneNumberRangesChanged): Pass ranges to
  the TelephoneNumberController.
* WebProcess/WebCoreSupport/WebEditorClient.h:

This controller handles installing/removing the PageOverlay, drawing the UI elements,
and handling mouse events while any of the UI elements are shown.
There’s also a clumsy attempt to keep platform-specific parts separated out.
* WebProcess/WebPage/TelephoneNumberOverlayController.cpp: Added.
(WebKit::TelephoneNumberOverlayController::TelephoneNumberOverlayController):
(WebKit::TelephoneNumberOverlayController::createOverlayIfNeeded):
(WebKit::TelephoneNumberOverlayController::destroyOverlay):
(WebKit::TelephoneNumberOverlayController::pageOverlayDestroyed):
(WebKit::TelephoneNumberOverlayController::willMoveToWebPage):
(WebKit::TelephoneNumberOverlayController::didMoveToWebPage):
(WebKit::TelephoneNumberOverlayController::rectsForDrawing):
(WebKit::TelephoneNumberOverlayController::selectedTelephoneNumberRangesChanged):

* WebProcess/WebPage/TelephoneNumberOverlayController.h: Added.
(WebKit::TelephoneNumberOverlayController::create):

* WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm: Added.
(WebKit::TelephoneNumberOverlayController::drawRect):
(WebKit::TelephoneNumberOverlayController::handleTelephoneClick):
(WebKit::TelephoneNumberOverlayController::mouseEvent):
(WebKit::TelephoneNumberOverlayController::clearMouseDownInformation):
(WebKit::TelephoneNumberOverlayController::clearHighlights):

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::telephoneNumberOverlayController):
* WebProcess/WebPage/WebPage.h:

* WebKit2.xcodeproj/project.pbxproj:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorh">trunk/Source/WebCore/editing/Editor.h</a></li>
<li><a href="#trunkSourceWebCorepageEditorClienth">trunk/Source/WebCore/page/EditorClient.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineTextBoxcpp">trunk/Source/WebCore/rendering/InlineTextBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineTextBoxh">trunk/Source/WebCore/rendering/InlineTextBox.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClientcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClienth">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2WebProcessWebPageTelephoneNumberOverlayControllercpp">trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageTelephoneNumberOverlayControllerh">trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacTelephoneNumberOverlayControllerMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/ChangeLog        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2014-04-04  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Show DataDetector UI on scanned phone numbers.
+        &lt;rdar://problem/16379588&gt; and https://bugs.webkit.org/show_bug.cgi?id=131247
+
+        Reviewed by Tim Horton.
+
+        Gather the ranges of the scanned telephone numbers and send them up to WK2:
+        * editing/Editor.cpp:
+        (WebCore::Editor::respondToChangedSelection):
+        (WebCore::Editor::scanSelectionForTelephoneNumbers):
+        (WebCore::Editor::scanRangeForTelephoneNumbers):
+        * editing/Editor.h:
+
+        Add client method to receive scanned telephone number ranges:
+        * page/EditorClient.h:
+        (WebCore::EditorClient::selectedTelephoneNumberRangesChanged):
+
+        Remove unneeded placeholder UI:
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintDocumentMarkers):
+        (WebCore::InlineTextBox::computeRectForReplacementMarker): Deleted.
+        (WebCore::InlineTextBox::paintCompositionUnderline): Deleted.
+        * rendering/InlineTextBox.h:
+        (WebCore::InlineTextBox::expansionBehavior): Deleted.
+
</ins><span class="cx"> 2014-04-04  James Craig  &lt;jcraig@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: supportsARIAExpanded should always return true for a few roles: combobox, disclosure.
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/editing/Editor.cpp        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -3318,7 +3318,10 @@
</span><span class="cx">         client()-&gt;respondToChangedSelection(&amp;m_frame);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TELEPHONE_NUMBER_DETECTION) &amp;&amp; !PLATFORM(IOS)
</span><del>-    scanSelectionForTelephoneNumbers();
</del><ins>+    Vector&lt;RefPtr&lt;Range&gt;&gt; markedRanges;
+    scanSelectionForTelephoneNumbers(markedRanges);
+    if (client())
+        client()-&gt;selectedTelephoneNumberRangesChanged(markedRanges);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     setStartNewKillRingSequence(true);
</span><span class="lines">@@ -3334,7 +3337,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TELEPHONE_NUMBER_DETECTION) &amp;&amp; !PLATFORM(IOS)
</span><del>-void Editor::scanSelectionForTelephoneNumbers()
</del><ins>+void Editor::scanSelectionForTelephoneNumbers(Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; markedRanges)
</ins><span class="cx"> {
</span><span class="cx">     if (!TelephoneNumberDetector::isSupported())
</span><span class="cx">         return;
</span><span class="lines">@@ -3350,16 +3353,16 @@
</span><span class="cx"> 
</span><span class="cx">     // FIXME: This won't work if a phone number spans multiple chunks of text from the perspective of the TextIterator
</span><span class="cx">     // (By a style change, image, line break, etc.)
</span><del>-    // On idea to handle this would be a model like text search that uses a rotating window.
</del><ins>+    // One idea to handle this would be a model like text search that uses a rotating window.
</ins><span class="cx">     for (TextIterator textChunk(selectedRange.get()); !textChunk.atEnd(); textChunk.advance()) {
</span><span class="cx">         // TextIterator is supposed to never returns a Range that spans multiple Nodes.
</span><span class="cx">         ASSERT(textChunk.range()-&gt;startContainer() == textChunk.range()-&gt;endContainer());
</span><span class="cx"> 
</span><del>-        scanRangeForTelephoneNumbers(*textChunk.range(), textChunk.text());
</del><ins>+        scanRangeForTelephoneNumbers(*textChunk.range(), textChunk.text(), markedRanges);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::scanRangeForTelephoneNumbers(Range&amp; range, const StringView&amp; stringView)
</del><ins>+void Editor::scanRangeForTelephoneNumbers(Range&amp; range, const StringView&amp; stringView, Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; markedRanges)
</ins><span class="cx"> {
</span><span class="cx">     // relativeStartPosition and relativeEndPosition are the endpoints of the phone number range,
</span><span class="cx">     // relative to the scannerPosition
</span><span class="lines">@@ -3383,8 +3386,12 @@
</span><span class="cx">         if (!range.startContainer()-&gt;isTextNode())
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        range.ownerDocument().markers().addMarkerToNode(range.startContainer(), range.startOffset() + scannerPosition + relativeStartPosition, relativeEndPosition - relativeStartPosition + 1, DocumentMarker::TelephoneNumber);
</del><ins>+        unsigned startOffset = range.startOffset() + scannerPosition + relativeStartPosition;
+        unsigned length = relativeEndPosition - relativeStartPosition + 1;
</ins><span class="cx"> 
</span><ins>+        markedRanges.append(Range::create(range.ownerDocument(), range.startContainer(), startOffset, range.startContainer(), startOffset + length));
+        range.ownerDocument().markers().addMarkerToNode(range.startContainer(), startOffset, length, DocumentMarker::TelephoneNumber);
+
</ins><span class="cx">         scannerPosition += relativeEndPosition + 1;
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.h (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.h        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/editing/Editor.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -474,8 +474,8 @@
</span><span class="cx">     bool unifiedTextCheckerEnabled() const;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TELEPHONE_NUMBER_DETECTION) &amp;&amp; !PLATFORM(IOS)
</span><del>-    void scanSelectionForTelephoneNumbers();
-    void scanRangeForTelephoneNumbers(Range&amp;, const StringView&amp;);
</del><ins>+    void scanSelectionForTelephoneNumbers(Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; markedRanges);
+    void scanRangeForTelephoneNumbers(Range&amp;, const StringView&amp;, Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; markedRanges);
</ins><span class="cx">     void clearDataDetectedTelephoneNumbers();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EditorClient.h (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EditorClient.h        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/page/EditorClient.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -178,6 +178,10 @@
</span><span class="cx">     virtual void willSetInputMethodState() = 0;
</span><span class="cx">     virtual void setInputMethodState(bool enabled) = 0;
</span><span class="cx"> 
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    virtual void selectedTelephoneNumberRangesChanged(const Vector&lt;RefPtr&lt;Range&gt;&gt;&amp;) { }
+#endif
+
</ins><span class="cx">     // Support for global selections, used on platforms like the X Window System that treat
</span><span class="cx">     // selection as a type of clipboard.
</span><span class="cx">     virtual bool supportsGlobalSelection() { return false; }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineTextBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineTextBox.cpp        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -1248,33 +1248,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(TELEPHONE_NUMBER_DETECTION)
-void InlineTextBox::paintTelephoneNumberMarker(GraphicsContext* ctx, const FloatPoint&amp; boxOrigin, DocumentMarker* marker, const RenderStyle&amp; style, const Font&amp; font)
-{
-    // FIXME: This is placeholder UI for development of the feature.
-
-    int startPosition = std::max&lt;int&gt;(marker-&gt;startOffset() - m_start, 0);
-    int endPosition = std::min&lt;int&gt;(marker-&gt;endOffset() - m_start, m_len);
-
-    if (m_truncation != cNoTruncation)
-        endPosition = std::min&lt;int&gt;(endPosition, m_truncation);
-
-    int deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
-    int selHeight = selectionHeight();
-    FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
-    TextRun run = constructTextRun(style, font);
-
-    IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
-
-    computeRectForReplacementMarker(marker, style, font);
-
-    Path outline;
-    outline.addRoundedRect(markerRect, FloatSize(4, 4));
-    ctx-&gt;setFillColor(Color(150, 150, 150, 255), ColorSpaceDeviceRGB);
-    ctx-&gt;fillPath(outline);
-}
-#endif // ENABLE(TELEPHONE_NUMBER_DETECTION)
-
</del><span class="cx"> void InlineTextBox::computeRectForReplacementMarker(DocumentMarker* marker, const RenderStyle&amp; style, const Font&amp; font)
</span><span class="cx"> {
</span><span class="cx">     // Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
</span><span class="lines">@@ -1363,7 +1336,6 @@
</span><span class="cx">                 break;
</span><span class="cx"> #if ENABLE(TELEPHONE_NUMBER_DETECTION)
</span><span class="cx">             case DocumentMarker::TelephoneNumber:
</span><del>-                paintTelephoneNumberMarker(pt, boxOrigin, marker, style, font);
</del><span class="cx">                 break;
</span><span class="cx"> #endif
</span><span class="cx">             default:
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineTextBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineTextBox.h        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -174,10 +174,6 @@
</span><span class="cx">     void paintDocumentMarker(GraphicsContext*, const FloatPoint&amp; boxOrigin, DocumentMarker*, const RenderStyle&amp;, const Font&amp;, bool grammar);
</span><span class="cx">     void paintTextMatchMarker(GraphicsContext*, const FloatPoint&amp; boxOrigin, DocumentMarker*, const RenderStyle&amp;, const Font&amp;);
</span><span class="cx"> 
</span><del>-#if ENABLE(TELEPHONE_NUMBER_DETECTION)
-    void paintTelephoneNumberMarker(GraphicsContext*, const FloatPoint&amp; boxOrigin, DocumentMarker*, const RenderStyle&amp;, const Font&amp;);
-#endif
-
</del><span class="cx">     void computeRectForReplacementMarker(DocumentMarker*, const RenderStyle&amp;, const Font&amp;);
</span><span class="cx"> 
</span><span class="cx">     TextRun::ExpansionBehavior expansionBehavior() const
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/ChangeLog        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2014-04-04  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Show DataDetector UI on scanned phone numbers.
+        &lt;rdar://problem/16379588&gt; and https://bugs.webkit.org/show_bug.cgi?id=131247
+
+        Reviewed by Tim Horton.
+
+        Add a new PageOverlay for telephone number UI, handle drawing the UI, and
+        handle mouse clicks on the button in that UI.
+
+        Even though clicks are detected, they aren’t acted upon yet.
+
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::selectedTelephoneNumberRangesChanged): Pass ranges to
+          the TelephoneNumberController.
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+
+        This controller handles installing/removing the PageOverlay, drawing the UI elements,
+        and handling mouse events while any of the UI elements are shown.
+        There’s also a clumsy attempt to keep platform-specific parts separated out.
+        * WebProcess/WebPage/TelephoneNumberOverlayController.cpp: Added.
+        (WebKit::TelephoneNumberOverlayController::TelephoneNumberOverlayController):
+        (WebKit::TelephoneNumberOverlayController::createOverlayIfNeeded):
+        (WebKit::TelephoneNumberOverlayController::destroyOverlay):
+        (WebKit::TelephoneNumberOverlayController::pageOverlayDestroyed):
+        (WebKit::TelephoneNumberOverlayController::willMoveToWebPage):
+        (WebKit::TelephoneNumberOverlayController::didMoveToWebPage):
+        (WebKit::TelephoneNumberOverlayController::rectsForDrawing):
+        (WebKit::TelephoneNumberOverlayController::selectedTelephoneNumberRangesChanged):
+
+        * WebProcess/WebPage/TelephoneNumberOverlayController.h: Added.
+        (WebKit::TelephoneNumberOverlayController::create):
+
+        * WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm: Added.
+        (WebKit::TelephoneNumberOverlayController::drawRect):
+        (WebKit::TelephoneNumberOverlayController::handleTelephoneClick):
+        (WebKit::TelephoneNumberOverlayController::mouseEvent):
+        (WebKit::TelephoneNumberOverlayController::clearMouseDownInformation):
+        (WebKit::TelephoneNumberOverlayController::clearHighlights):
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::telephoneNumberOverlayController):
+        * WebProcess/WebPage/WebPage.h:
+
+        * WebKit2.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2014-04-04  Martin Hock  &lt;mhock@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Include Session ID in WebPageCreationParameters.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -852,6 +852,8 @@
</span><span class="cx">                 518E8F0B16B2093700E91429 /* DownloadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 518E8F0216B2093700E91429 /* DownloadManager.cpp */; };
</span><span class="cx">                 518E8F0C16B2093700E91429 /* DownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 518E8F0316B2093700E91429 /* DownloadManager.h */; };
</span><span class="cx">                 518E8F0D16B2093700E91429 /* DownloadMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 518E8F0516B2093700E91429 /* DownloadMac.mm */; };
</span><ins>+                519EF58E18EF770D0003B7F4 /* TelephoneNumberOverlayControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 519EF58D18EF770D0003B7F4 /* TelephoneNumberOverlayControllerMac.mm */; };
+                519EF59218EF80CE0003B7F4 /* TelephoneNumberOverlayController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 519EF58F18EF77210003B7F4 /* TelephoneNumberOverlayController.cpp */; };
</ins><span class="cx">                 51A4D5A916CAC4FF000E615E /* StatisticsRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A4D5A816CAC4FF000E615E /* StatisticsRequest.cpp */; };
</span><span class="cx">                 51A555F5128C6C47009ABCEC /* WKContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A555F3128C6C47009ABCEC /* WKContextMenuItem.cpp */; };
</span><span class="cx">                 51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A555F4128C6C47009ABCEC /* WKContextMenuItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2673,6 +2675,9 @@
</span><span class="cx">                 518E8F0216B2093700E91429 /* DownloadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DownloadManager.cpp; path = Downloads/DownloadManager.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 518E8F0316B2093700E91429 /* DownloadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DownloadManager.h; path = Downloads/DownloadManager.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 518E8F0516B2093700E91429 /* DownloadMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DownloadMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                519EF58D18EF770D0003B7F4 /* TelephoneNumberOverlayControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TelephoneNumberOverlayControllerMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                519EF58F18EF77210003B7F4 /* TelephoneNumberOverlayController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TelephoneNumberOverlayController.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                519EF59018EF77210003B7F4 /* TelephoneNumberOverlayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TelephoneNumberOverlayController.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 51A4D5A816CAC4FF000E615E /* StatisticsRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StatisticsRequest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51A555F3128C6C47009ABCEC /* WKContextMenuItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKContextMenuItem.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51A555F4128C6C47009ABCEC /* WKContextMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContextMenuItem.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5317,6 +5322,8 @@
</span><span class="cx">                                 7CF47FF917275C57008ACB91 /* PageBanner.h */,
</span><span class="cx">                                 1A90C23612650717003E44D4 /* PageOverlay.cpp */,
</span><span class="cx">                                 1A90C23512650717003E44D4 /* PageOverlay.h */,
</span><ins>+                                519EF58F18EF77210003B7F4 /* TelephoneNumberOverlayController.cpp */,
+                                519EF59018EF77210003B7F4 /* TelephoneNumberOverlayController.h */,
</ins><span class="cx">                                 2D819B99186275B3001F03D1 /* ViewGestureGeometryCollector.cpp */,
</span><span class="cx">                                 2D819B9A186275B3001F03D1 /* ViewGestureGeometryCollector.h */,
</span><span class="cx">                                 2D819B9B186275B3001F03D1 /* ViewGestureGeometryCollector.messages.in */,
</span><span class="lines">@@ -6066,6 +6073,7 @@
</span><span class="cx">                                 1AB16AE7164B3A8800290D62 /* RemoteLayerTreeContext.mm */,
</span><span class="cx">                                 1AB16ADC1648598400290D62 /* RemoteLayerTreeDrawingArea.h */,
</span><span class="cx">                                 1AB16ADB1648598400290D62 /* RemoteLayerTreeDrawingArea.mm */,
</span><ins>+                                519EF58D18EF770D0003B7F4 /* TelephoneNumberOverlayControllerMac.mm */,
</ins><span class="cx">                                 1AAF263714687C39004A1E8A /* TiledCoreAnimationDrawingArea.h */,
</span><span class="cx">                                 1AAF263614687C39004A1E8A /* TiledCoreAnimationDrawingArea.mm */,
</span><span class="cx">                                 1C8E2DAD1278C5B200BC7BD0 /* WebInspectorMac.mm */,
</span><span class="lines">@@ -8500,9 +8508,11 @@
</span><span class="cx">                                 33D3A3BA1339606200709BE4 /* WebMediaCacheManagerProxy.cpp in Sources */,
</span><span class="cx">                                 33D3A3CA1339617900709BE4 /* WebMediaCacheManagerProxyMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 0FCB4E4D18BBE044000FCFC9 /* WKContentView.mm in Sources */,
</span><ins>+                                519EF59218EF80CE0003B7F4 /* TelephoneNumberOverlayController.cpp in Sources */,
</ins><span class="cx">                                 909854EC12BC4E17000AD080 /* WebMemorySampler.cpp in Sources */,
</span><span class="cx">                                 909854EE12BC4E18000AD080 /* WebMemorySampler.mac.mm in Sources */,
</span><span class="cx">                                 C0337DB0127A28D0008FF4F4 /* WebMouseEvent.cpp in Sources */,
</span><ins>+                                519EF58E18EF770D0003B7F4 /* TelephoneNumberOverlayControllerMac.mm in Sources */,
</ins><span class="cx">                                 BCF69FA31176D01400471A52 /* APINavigationData.cpp in Sources */,
</span><span class="cx">                                 31A2EC48148997C200810D71 /* WebNotification.cpp in Sources */,
</span><span class="cx">                                 31099973146C75A20029DEB9 /* WebNotificationClient.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include &quot;WebEditorClient.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;EditorState.h&quot;
</span><ins>+#include &quot;TelephoneNumberOverlayController.h&quot;
</ins><span class="cx"> #include &quot;WebCoreArgumentCoders.h&quot;
</span><span class="cx"> #include &quot;WebFrame.h&quot;
</span><span class="cx"> #include &quot;WebPage.h&quot;
</span><span class="lines">@@ -500,4 +501,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+void WebEditorClient::selectedTelephoneNumberRangesChanged(const Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; ranges)
+{
+    m_page-&gt;telephoneNumberOverlayController().selectedTelephoneNumberRangesChanged(ranges);
+}
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -167,6 +167,10 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool supportsGlobalSelection() override;
</span><span class="cx"> 
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    virtual void selectedTelephoneNumberRangesChanged(const Vector&lt;RefPtr&lt;WebCore::Range&gt;&gt;&amp;) override;
+#endif
+
</ins><span class="cx">     WebPage* m_page;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageTelephoneNumberOverlayControllercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.cpp (0 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.cpp                                (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.cpp        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TelephoneNumberOverlayController.h&quot;
+
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+
+#include &quot;WebPage.h&quot;
+
+using namespace WebCore;
+
+namespace WebKit {
+    
+TelephoneNumberOverlayController::TelephoneNumberOverlayController(WebPage* webPage)
+    : m_webPage(webPage)
+    , m_telephoneNumberOverlay(nullptr)
+{
+    ASSERT(m_webPage);
+}
+
+void TelephoneNumberOverlayController::createOverlayIfNeeded()
+{
+    if (m_telephoneNumberOverlay) {
+        m_telephoneNumberOverlay-&gt;setNeedsDisplay();
+        return;
+    }
+    
+    RefPtr&lt;PageOverlay&gt; overlay = PageOverlay::create(this);
+    m_telephoneNumberOverlay = overlay.get();
+    m_webPage-&gt;installPageOverlay(overlay.release(), true);
+    m_telephoneNumberOverlay-&gt;setNeedsDisplay();
+}
+
+void TelephoneNumberOverlayController::destroyOverlay()
+{
+    if (!m_telephoneNumberOverlay)
+        return;
+
+    m_webPage-&gt;uninstallPageOverlay(m_telephoneNumberOverlay, false);
+}
+
+void TelephoneNumberOverlayController::pageOverlayDestroyed(PageOverlay*)
+{
+    // Before the overlay is destroyed, it should have moved out of the WebPage,
+    // at which point we already cleared our back pointer.
+    ASSERT(!m_telephoneNumberOverlay);
+}
+
+void TelephoneNumberOverlayController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
+{
+    if (webPage)
+        return;
+
+    ASSERT(m_telephoneNumberOverlay);
+    m_telephoneNumberOverlay = 0;
+}
+
+void TelephoneNumberOverlayController::didMoveToWebPage(PageOverlay*, WebPage*)
+{
+}
+
+Vector&lt;IntRect&gt; TelephoneNumberOverlayController::rectsForDrawing() const
+{
+    Vector&lt;IntRect&gt; result;
+    
+    // FIXME: This will choke if the range wraps around the edge of the view.
+    // What should we do in that case?
+    for (auto&amp; range : m_currentSelectionRanges)
+        result.append(enclosingIntRect(range-&gt;boundingRect()));
+
+    return result;
+}
+
+void TelephoneNumberOverlayController::selectedTelephoneNumberRangesChanged(const Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; ranges)
+{
+#if PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 1090
+    m_currentSelectionRanges = ranges;
+    
+    clearHighlights();
+    
+    if (m_currentSelectionRanges.isEmpty())
+        destroyOverlay();
+    else
+        createOverlayIfNeeded();
+#else
+    UNUSED_PARAM(ranges);
+#endif
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(TELEPHONE_NUMBER_DETECTION)
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageTelephoneNumberOverlayControllerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.h (0 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.h                                (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebPage/TelephoneNumberOverlayController.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TelephoneNumberOverlayController_h
+
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+
+#include &quot;PageOverlay.h&quot;
+#include &lt;WebCore/IntRect.h&gt;
+#include &lt;wtf/RefCounted.h&gt;
+
+namespace WebCore {
+class Range;
+}
+
+namespace WebKit {
+    
+class WebPage;
+    
+#if PLATFORM(MAC)
+typedef void* DDHighlightRef;
+#endif
+
+class TelephoneNumberOverlayController : public RefCounted&lt;TelephoneNumberOverlayController&gt;, private PageOverlay::Client {
+public:
+
+    static PassRefPtr&lt;TelephoneNumberOverlayController&gt; create(WebPage* webPage)
+    {
+        return adoptRef(new TelephoneNumberOverlayController(webPage));
+    }
+
+    void selectedTelephoneNumberRangesChanged(const Vector&lt;RefPtr&lt;WebCore::Range&gt;&gt;&amp;);
+    
+private:
+    TelephoneNumberOverlayController(WebPage*);
+
+    void createOverlayIfNeeded();
+    void destroyOverlay();
+    
+    void clearHighlights();
+    void clearMouseDownInformation();
+    
+    void handleTelephoneClick();
+    
+    Vector&lt;WebCore::IntRect&gt; rectsForDrawing() const;
+
+    virtual void pageOverlayDestroyed(PageOverlay*) override;
+    virtual void willMoveToWebPage(PageOverlay*, WebPage*) override;
+    virtual void didMoveToWebPage(PageOverlay*, WebPage*) override;
+    virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&amp;, const WebCore::IntRect&amp; dirtyRect) override;
+    virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&amp;) override;
+
+    RefPtr&lt;WebPage&gt; m_webPage;
+    PageOverlay* m_telephoneNumberOverlay;
+    Vector&lt;RefPtr&lt;WebCore::Range&gt;&gt; m_currentSelectionRanges;
+    
+    
+#if PLATFORM(MAC)
+    Vector&lt;RetainPtr&lt;DDHighlightRef&gt;&gt; m_highlights;
+    RetainPtr&lt;DDHighlightRef&gt; m_currentMouseDownHighlight;
+#endif
+    
+    WebCore::IntPoint m_mouseDownPosition;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(TELEPHONE_NUMBER_DETECTION)
+#endif // TelephoneNumberOverlayController_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> #include &quot;SessionState.h&quot;
</span><span class="cx"> #include &quot;SessionTracker.h&quot;
</span><span class="cx"> #include &quot;ShareableBitmap.h&quot;
</span><ins>+#include &quot;TelephoneNumberOverlayController.h&quot;
</ins><span class="cx"> #include &quot;VisitedLinkTableController.h&quot;
</span><span class="cx"> #include &quot;WKSharedAPICast.h&quot;
</span><span class="cx"> #include &quot;WebAlternativeTextClient.h&quot;
</span><span class="lines">@@ -4544,5 +4545,14 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx">     
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+TelephoneNumberOverlayController&amp; WebPage::telephoneNumberOverlayController()
+{
+    if (!m_telephoneNumberOverlayController)
+        m_telephoneNumberOverlayController = TelephoneNumberOverlayController::create(this);
</ins><span class="cx"> 
</span><ins>+    return *m_telephoneNumberOverlayController;
+}
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (166817 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-04-05 00:37:55 UTC (rev 166817)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -178,6 +178,10 @@
</span><span class="cx"> class WebTouchEvent;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+class TelephoneNumberOverlayController;
+#endif
+
</ins><span class="cx"> typedef Vector&lt;RefPtr&lt;PageOverlay&gt;&gt; PageOverlayList;
</span><span class="cx"> 
</span><span class="cx"> class WebPage : public API::ObjectImpl&lt;API::Object::Type::BundlePage&gt;, public IPC::MessageReceiver, public IPC::MessageSender {
</span><span class="lines">@@ -770,6 +774,10 @@
</span><span class="cx">     // While this is not ideal, it does not have to be applied to every platform at the moment.
</span><span class="cx">     static bool synchronousMessagesShouldSpinRunLoop();
</span><span class="cx">     
</span><ins>+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    TelephoneNumberOverlayController&amp; telephoneNumberOverlayController();
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx">     WebPage(uint64_t pageID, const WebPageCreationParameters&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -1172,6 +1180,10 @@
</span><span class="cx"> #if ENABLE(WEBGL)
</span><span class="cx">     WebCore::WebGLLoadPolicy m_systemWebGLPolicy;
</span><span class="cx"> #endif
</span><ins>+
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    RefPtr&lt;TelephoneNumberOverlayController&gt; m_telephoneNumberOverlayController;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacTelephoneNumberOverlayControllerMacmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm (0 => 166818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm                                (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/TelephoneNumberOverlayControllerMac.mm        2014-04-05 01:10:11 UTC (rev 166818)
</span><span class="lines">@@ -0,0 +1,183 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import &quot;config.h&quot;
+#import &quot;TelephoneNumberOverlayController.h&quot;
+
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+
+#import &quot;WebPage.h&quot;
+#import &lt;WebCore/FrameView.h&gt;
+#import &lt;WebCore/GraphicsContext.h&gt;
+#import &lt;WebCore/MainFrame.h&gt;
+#import &lt;WebCore/SoftLinking.h&gt;
+
+#if __has_include(&lt;DataDetectors/DDHighlightDrawing.h&gt;)
+#import &lt;DataDetectors/DDHighlightDrawing.h&gt;
+#import &lt;DataDetectors/DDHighlightDrawing_Private.h&gt;
+#else
+typedef void* DDHighlightRef;
+#endif
+
+SOFT_LINK_PRIVATE_FRAMEWORK_OPTIONAL(DataDetectors)
+SOFT_LINK(DataDetectors, DDHighlightCreateWithRectsInVisibleRect, DDHighlightRef, (CFAllocatorRef allocator, CGRect * rects, CFIndex count, CGRect globalVisibleRect, Boolean withArrow), (allocator, rects, count, globalVisibleRect, withArrow))
+SOFT_LINK(DataDetectors, DDHighlightGetLayerWithContext, CGLayerRef, (DDHighlightRef highlight, CGContextRef context), (highlight, context))
+SOFT_LINK(DataDetectors, DDHighlightGetBoundingRect, CGRect, (DDHighlightRef highlight), (highlight))
+SOFT_LINK(DataDetectors, DDHighlightPointIsOnHighlight, Boolean, (DDHighlightRef highlight, CGPoint point, Boolean* onButton), (highlight, point, onButton))
+SOFT_LINK(DataDetectors, DDHighlightSetButtonPressed, void, (DDHighlightRef highlight, Boolean buttonPressed), (highlight, buttonPressed))
+
+using namespace WebCore;
+
+namespace WebKit {
+    
+void TelephoneNumberOverlayController::drawRect(PageOverlay* overlay, WebCore::GraphicsContext&amp; graphicsContext, const WebCore::IntRect&amp; dirtyRect)
+{
+    Vector&lt;IntRect&gt; rects = rectsForDrawing();
+    if (rects.isEmpty())
+        return;
+    
+    clearHighlights();
+    
+    CGContextRef cgContext = graphicsContext.platformContext();
+    
+    for (auto&amp; rect : rects) {
+        CGRect cgRects[] = { (CGRect)rect };
+        DDHighlightRef highlight = DDHighlightCreateWithRectsInVisibleRect(nullptr, cgRects, 1, (CGRect)dirtyRect, true);
+        m_highlights.append(adoptCF(highlight));
+        
+        // Check and see if the mouse is currently down inside this highlight's button.
+        if (m_mouseDownPosition != IntPoint()) {
+            Boolean onButton;
+            if (DDHighlightPointIsOnHighlight(highlight, (CGPoint)m_mouseDownPosition, &amp;onButton)) {
+                if (onButton) {
+                    m_currentMouseDownHighlight = highlight;
+                    
+                    // FIXME: We need to do the following, but SOFT_LINK isn't working for this method.
+                    // DDHighlightSetButtonPressed(highlight, true);
+                }
+            }
+        }
+        
+        CGLayerRef highlightLayer = DDHighlightGetLayerWithContext(highlight, cgContext);
+        CGRect highlightBoundingRect = DDHighlightGetBoundingRect(highlight);
+        
+        GraphicsContextStateSaver stateSaver(graphicsContext);
+
+        graphicsContext.translate(toFloatSize(highlightBoundingRect.origin));
+        graphicsContext.scale(FloatSize(1, -1));
+        graphicsContext.translate(FloatSize(0, -highlightBoundingRect.size.height));
+        
+        CGRect highlightDrawRect = highlightBoundingRect;
+        highlightDrawRect.origin.x = 0;
+        highlightDrawRect.origin.y = 0;
+        
+        CGContextDrawLayerInRect(cgContext, highlightDrawRect, highlightLayer);
+    }
+}
+    
+void TelephoneNumberOverlayController::handleTelephoneClick()
+{
+    // FIXME: Handle the button click here.
+}
+    
+bool TelephoneNumberOverlayController::mouseEvent(PageOverlay*, const WebMouseEvent&amp; event)
+{
+    IntPoint mousePosition = m_webPage-&gt;corePage()-&gt;mainFrame().view()-&gt;rootViewToContents(event.position());
+    
+    // If this event has nothing to do with the left button, it clears the current mouse down tracking and we're done processing it.
+    if (event.button() != WebMouseEvent::LeftButton) {
+        clearMouseDownInformation();
+        return false;
+    }
+    
+    RetainPtr&lt;DDHighlightRef&gt; currentHighlight = m_currentMouseDownHighlight;
+    
+    // Check and see if the mouse went up and we have a current mouse down highlight button.
+    if (event.type() == WebEvent::MouseUp &amp;&amp; currentHighlight) {
+        clearMouseDownInformation();
+        
+        // If the mouse lifted while still over the highlight button that it went down on, then that is a click.
+        Boolean onButton;
+        if (DDHighlightPointIsOnHighlight(currentHighlight.get(), (CGPoint)mousePosition, &amp;onButton) &amp;&amp; onButton) {
+            handleTelephoneClick();
+            
+            return true;
+        }
+        
+        return false;
+    }
+    
+    // Check and see if the mouse moved within the confines of the DD highlight button.
+    if (event.type() == WebEvent::MouseMove &amp;&amp; currentHighlight) {
+        Boolean onButton;
+        
+        // Moving with the mouse button down is okay as long as the mouse never leaves the highlight button.
+        if (DDHighlightPointIsOnHighlight(currentHighlight.get(), (CGPoint)mousePosition, &amp;onButton) &amp;&amp; onButton)
+            return true;
+        
+        clearMouseDownInformation();
+        
+        return false;
+    }
+    
+    // Check and see if the mouse went down over a DD highlight button.
+    if (event.type() == WebEvent::MouseDown) {
+        ASSERT(!m_currentMouseDownHighlight);
+        
+        for (auto&amp; highlight : m_highlights) {
+            Boolean onButton;
+            if (DDHighlightPointIsOnHighlight(highlight.get(), (CGPoint)mousePosition, &amp;onButton) &amp;&amp; onButton) {
+                m_mouseDownPosition = mousePosition;
+                m_currentMouseDownHighlight = highlight;
+                
+                // FIXME: We need to do the following, but SOFT_LINK isn't working for this method.
+                // DDHighlightSetButtonPressed(highlight.get(), true);
+                
+                m_telephoneNumberOverlay-&gt;setNeedsDisplay();
+                return true;
+            }
+        }
+        
+        return false;
+    }
+        
+    return false;
+}
+    
+void TelephoneNumberOverlayController::clearMouseDownInformation()
+{
+    m_currentMouseDownHighlight = nullptr;
+    m_mouseDownPosition = IntPoint();
+}
+    
+void TelephoneNumberOverlayController::clearHighlights()
+{
+    m_highlights.clear();    
+    m_currentMouseDownHighlight = nullptr;
+}
+    
+}
+
+#endif // ENABLE(TELEPHONE_NUMBER_DETECTION)
</ins></span></pre>
</div>
</div>

</body>
</html>