<!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>[163255] 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/163255">163255</a></dd>
<dt>Author</dt> <dd>enrica@apple.com</dd>
<dt>Date</dt> <dd>2014-02-01 18:37:43 -0800 (Sat, 01 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for ActionSheets in WK2 for iOS.
https://bugs.webkit.org/show_bug.cgi?id=127586
&lt;rdar://problem/15283667&gt;

Reviewed by Benjamin Poulain.

Source/WebCore: 

Updates the localizable strings for action sheets.

* English.lproj/Localizable.strings:

Source/WebKit2: 

This patch adds the default support for Action Sheets
in WK2 for iOS. WKActionSheet is the implementation of the
sheet itself that inherits from UIActionSheet and handles
the repositioning of the sheet after rotation for iPad.
WKActionSheetAssistant is the controller class that implements
the delegate methods, controls the lifetime of the action sheet
object and performs the actions.
We have 3 different types of sheets:
   - link sheet, displayed when the target element is a link
   - image sheet, when the target element is an image
   - data detector sheet when the target is an element
     recognized by the data detectors library.
Both link and image sheet have a set of default buttons, whereas
datadetector sheet in only populated by custom actions provided
by data detectors.
The link sheet provides the following default actions:
    - open, navigates to the URL
    - copy, copies the URL to the pasteboard
    - add to reading list
The image sheet provides the following actions depending on whether
the image is contained inside an anchor element or not.
If the image is NOT inside a link the following actions are provided:
   - copy, copies the image to the pasteboard
   - save image, saves the image in the photo library
Instead, if the image is inside an link:
   - open, navigates to the URL spcified by the link
   - copy, copies the link URL to the pasteboard
    - save image, saves the image in the photo library
    - add to reading list, adds the link URL to reading list.

* Shared/InteractionInformationAtPosition.cpp:
(WebKit::InteractionInformationAtPosition::encode):
(WebKit::InteractionInformationAtPosition::decode):
* Shared/InteractionInformationAtPosition.h:
* Shared/ios/WKGestureTypes.h:
* UIProcess/API/ios/PageClientImplIOS.h:
* UIProcess/API/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::saveImageToLibrary):
* UIProcess/API/ios/WKActionSheet.h: Added.
* UIProcess/API/ios/WKActionSheet.mm: Added.
(-[WKActionSheet initWithView:]):
(-[WKActionSheet dealloc]):
(-[WKActionSheet presentSheet]):
(-[WKActionSheet presentSheetFromRect:]):
(-[WKActionSheet doneWithSheet]):
(-[WKActionSheet willRotate]):
(-[WKActionSheet updateSheetPosition]):
(-[WKActionSheet didRotate]):
(-[WKElementActionInfo initWithInfo:location:title:rect:]):
(-[WKElementActionInfo dealloc]):
(-[WKElementAction initWithTitle:actionHandler:type:]):
(-[WKElementAction dealloc]):
(+[WKElementAction customElementActionWithTitle:actionHandler:]):
(copyElement):
(saveImage):
(addToReadingList):
(+[WKElementAction standardElementActionWithType:customTitle:]):
(+[WKElementAction standardElementActionWithType:]):
(-[WKElementAction runActionWithElementInfo:view:]):
* UIProcess/API/ios/WKActionSheetAssistant.h: Added.
* UIProcess/API/ios/WKActionSheetAssistant.mm: Added.
(-[WKActionSheetAssistant initWithView:]):
(-[WKActionSheetAssistant dealloc]):
(-[WKActionSheetAssistant setPage:WebKit::]):
(-[WKActionSheetAssistant superviewForSheet]):
(-[WKActionSheetAssistant _presentationRectForSheetGivenPoint:inHostView:]):
(-[WKActionSheetAssistant hostViewForSheet]):
(-[WKActionSheetAssistant initialPresentationRectInHostViewForSheet]):
(-[WKActionSheetAssistant presentationRectInHostViewForSheet]):
(-[WKActionSheetAssistant presentSheet]):
(-[WKActionSheetAssistant actionSheet:clickedButtonAtIndex:]):
(-[WKActionSheetAssistant updateSheetPosition]):
(-[WKActionSheetAssistant _createSheetWithElementActions:showLinkTitle:]):
(-[WKActionSheetAssistant showImageSheet]):
(-[WKActionSheetAssistant showLinkSheet]):
(-[WKActionSheetAssistant showDataDetectorsSheet]):
(-[WKActionSheetAssistant cleanupSheet]):
* UIProcess/API/ios/WKInteractionView.h:
* UIProcess/API/ios/WKInteractionView.mm:
(-[WKInteractionView initWithFrame:]):
(-[WKInteractionView dealloc]):
(-[WKInteractionView setPage:WebKit::]):
(-[WKInteractionView _showImageSheet]):
(-[WKInteractionView _showLinkSheet]):
(-[WKInteractionView _showDataDetectorsSheet]):
(-[WKInteractionView _actionForLongPress]):
(-[WKInteractionView _updatePositionInformation]):
(-[WKInteractionView _longPressRecognized:]):
(-[WKInteractionView _positionInformationDidChange:]):
(-[WKInteractionView _performAction:]):
(-[WKInteractionView _updateAccessory]):
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::startInteractionWithElementAtPosition):
(WebKit::WebPageProxy::stopInteraction):
(WebKit::WebPageProxy::performActionOnElement):
(WebKit::WebPageProxy::saveImageToLibrary):
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::containingLinkElement):
(WebKit::WebPage::getPositionInformation):
(WebKit::WebPage::startInteractionWithElementAtPosition):
(WebKit::WebPage::stopInteraction):
(WebKit::WebPage::performActionOnElement):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreEnglishlprojLocalizablestrings">trunk/Source/WebCore/English.lproj/Localizable.strings</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="#trunkSourceWebKit2SharediosWKGestureTypesh">trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosPageClientImplIOSh">trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosPageClientImplIOSmm">trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKInteractionViewh">trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKInteractionViewmm">trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKActionSheeth">trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKActionSheetmm">trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKActionSheetAssistanth">trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIiosWKActionSheetAssistantmm">trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebCore/ChangeLog        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-02-01  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        Add support for ActionSheets in WK2 for iOS.
+        https://bugs.webkit.org/show_bug.cgi?id=127586
+        &lt;rdar://problem/15283667&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        Updates the localizable strings for action sheets.
+
+        * English.lproj/Localizable.strings:
+
</ins><span class="cx"> 2014-02-01  Maciej Stachowiak  &lt;mjs@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Factor URL decomposition methods (from URLUtils interface) into a base template
</span></span></pre></div>
<a id="trunkSourceWebCoreEnglishlprojLocalizablestrings"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/English.lproj/Localizable.strings (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/English.lproj/Localizable.strings        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebCore/English.lproj/Localizable.strings        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -64,6 +64,9 @@
</span><span class="cx"> /* window title for a standalone image (uses multiplication symbol, not x) */
</span><span class="cx"> &quot;&lt;filename&gt; %d×%d pixels&quot; = &quot;&lt;filename&gt; %d×%d pixels&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for Add to Reading List action button */
+&quot;Add to Reading List&quot; = &quot;Add to Reading List&quot;;
+
</ins><span class="cx"> /* Undo action name */
</span><span class="cx"> &quot;Align Left (Undo action name)&quot; = &quot;Align Left&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -88,6 +91,9 @@
</span><span class="cx"> /* Undo action name */
</span><span class="cx"> &quot;Bold (Undo action name)&quot; = &quot;Bold&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for Cancel button label in button bar */
+&quot;Cancel button label in button bar&quot; = &quot;Cancel&quot;;
+
</ins><span class="cx"> /* Capitalize context menu item */
</span><span class="cx"> &quot;Capitalize&quot; = &quot;Capitalize&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -136,6 +142,9 @@
</span><span class="cx"> /* Copy context menu item */
</span><span class="cx"> &quot;Copy&quot; = &quot;Copy&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for Copy Link or Image action button */
+&quot;Copy ActionSheet Link&quot; = &quot;Copy&quot;;
+
</ins><span class="cx"> /* Copy Audio Address Location context menu item */
</span><span class="cx"> &quot;Copy Audio Address&quot; = &quot;Copy Audio Address&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -247,6 +256,9 @@
</span><span class="cx"> /* WebKitErrorJavaUnavailable description */
</span><span class="cx"> &quot;Java is unavailable&quot; = &quot;Java is unavailable&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for action sheet for JavaScript link */
+&quot;JavaScript Action Sheet Title&quot; = &quot;JavaScript&quot;;
+
</ins><span class="cx"> /* Undo action name */
</span><span class="cx"> &quot;Justify (Undo action name)&quot; = &quot;Justify&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -307,6 +319,9 @@
</span><span class="cx"> /* Menu item label for the track that represents disabling closed captions */
</span><span class="cx"> &quot;Off&quot; = &quot;Off&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for Open Link action button */
+&quot;Open ActionSheet Link&quot; = &quot;Open&quot;;
+
</ins><span class="cx"> /* Open Audio in New Window context menu item */
</span><span class="cx"> &quot;Open Audio in New Window&quot; = &quot;Open Audio in New Window&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -391,6 +406,9 @@
</span><span class="cx"> /* Right to Left context menu item */
</span><span class="cx"> &quot;Right to Left&quot; = &quot;Right to Left&quot;;
</span><span class="cx"> 
</span><ins>+/* Title for Save Image action button */
+&quot;Save Image&quot; = &quot;Save Image&quot;;
+
</ins><span class="cx"> /* Search in Spotlight context menu item */
</span><span class="cx"> &quot;Search in Spotlight&quot; = &quot;Search in Spotlight&quot;;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/ChangeLog        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -1,3 +1,120 @@
</span><ins>+2014-02-01  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        Add support for ActionSheets in WK2 for iOS.
+        https://bugs.webkit.org/show_bug.cgi?id=127586
+        &lt;rdar://problem/15283667&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        This patch adds the default support for Action Sheets
+        in WK2 for iOS. WKActionSheet is the implementation of the
+        sheet itself that inherits from UIActionSheet and handles
+        the repositioning of the sheet after rotation for iPad.
+        WKActionSheetAssistant is the controller class that implements
+        the delegate methods, controls the lifetime of the action sheet
+        object and performs the actions.
+        We have 3 different types of sheets:
+           - link sheet, displayed when the target element is a link
+           - image sheet, when the target element is an image
+           - data detector sheet when the target is an element
+             recognized by the data detectors library.
+        Both link and image sheet have a set of default buttons, whereas
+        datadetector sheet in only populated by custom actions provided
+        by data detectors.
+        The link sheet provides the following default actions:
+            - open, navigates to the URL
+            - copy, copies the URL to the pasteboard
+            - add to reading list
+        The image sheet provides the following actions depending on whether
+        the image is contained inside an anchor element or not.
+        If the image is NOT inside a link the following actions are provided:
+           - copy, copies the image to the pasteboard
+           - save image, saves the image in the photo library
+        Instead, if the image is inside an link:
+           - open, navigates to the URL spcified by the link
+           - copy, copies the link URL to the pasteboard
+            - save image, saves the image in the photo library
+            - add to reading list, adds the link URL to reading list.
+
+        * Shared/InteractionInformationAtPosition.cpp:
+        (WebKit::InteractionInformationAtPosition::encode):
+        (WebKit::InteractionInformationAtPosition::decode):
+        * Shared/InteractionInformationAtPosition.h:
+        * Shared/ios/WKGestureTypes.h:
+        * UIProcess/API/ios/PageClientImplIOS.h:
+        * UIProcess/API/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::saveImageToLibrary):
+        * UIProcess/API/ios/WKActionSheet.h: Added.
+        * UIProcess/API/ios/WKActionSheet.mm: Added.
+        (-[WKActionSheet initWithView:]):
+        (-[WKActionSheet dealloc]):
+        (-[WKActionSheet presentSheet]):
+        (-[WKActionSheet presentSheetFromRect:]):
+        (-[WKActionSheet doneWithSheet]):
+        (-[WKActionSheet willRotate]):
+        (-[WKActionSheet updateSheetPosition]):
+        (-[WKActionSheet didRotate]):
+        (-[WKElementActionInfo initWithInfo:location:title:rect:]):
+        (-[WKElementActionInfo dealloc]):
+        (-[WKElementAction initWithTitle:actionHandler:type:]):
+        (-[WKElementAction dealloc]):
+        (+[WKElementAction customElementActionWithTitle:actionHandler:]):
+        (copyElement):
+        (saveImage):
+        (addToReadingList):
+        (+[WKElementAction standardElementActionWithType:customTitle:]):
+        (+[WKElementAction standardElementActionWithType:]):
+        (-[WKElementAction runActionWithElementInfo:view:]):
+        * UIProcess/API/ios/WKActionSheetAssistant.h: Added.
+        * UIProcess/API/ios/WKActionSheetAssistant.mm: Added.
+        (-[WKActionSheetAssistant initWithView:]):
+        (-[WKActionSheetAssistant dealloc]):
+        (-[WKActionSheetAssistant setPage:WebKit::]):
+        (-[WKActionSheetAssistant superviewForSheet]):
+        (-[WKActionSheetAssistant _presentationRectForSheetGivenPoint:inHostView:]):
+        (-[WKActionSheetAssistant hostViewForSheet]):
+        (-[WKActionSheetAssistant initialPresentationRectInHostViewForSheet]):
+        (-[WKActionSheetAssistant presentationRectInHostViewForSheet]):
+        (-[WKActionSheetAssistant presentSheet]):
+        (-[WKActionSheetAssistant actionSheet:clickedButtonAtIndex:]):
+        (-[WKActionSheetAssistant updateSheetPosition]):
+        (-[WKActionSheetAssistant _createSheetWithElementActions:showLinkTitle:]):
+        (-[WKActionSheetAssistant showImageSheet]):
+        (-[WKActionSheetAssistant showLinkSheet]):
+        (-[WKActionSheetAssistant showDataDetectorsSheet]):
+        (-[WKActionSheetAssistant cleanupSheet]):
+        * UIProcess/API/ios/WKInteractionView.h:
+        * UIProcess/API/ios/WKInteractionView.mm:
+        (-[WKInteractionView initWithFrame:]):
+        (-[WKInteractionView dealloc]):
+        (-[WKInteractionView setPage:WebKit::]):
+        (-[WKInteractionView _showImageSheet]):
+        (-[WKInteractionView _showLinkSheet]):
+        (-[WKInteractionView _showDataDetectorsSheet]):
+        (-[WKInteractionView _actionForLongPress]):
+        (-[WKInteractionView _updatePositionInformation]):
+        (-[WKInteractionView _longPressRecognized:]):
+        (-[WKInteractionView _positionInformationDidChange:]):
+        (-[WKInteractionView _performAction:]):
+        (-[WKInteractionView _updateAccessory]):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::startInteractionWithElementAtPosition):
+        (WebKit::WebPageProxy::stopInteraction):
+        (WebKit::WebPageProxy::performActionOnElement):
+        (WebKit::WebPageProxy::saveImageToLibrary):
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::containingLinkElement):
+        (WebKit::WebPage::getPositionInformation):
+        (WebKit::WebPage::startInteractionWithElementAtPosition):
+        (WebKit::WebPage::stopInteraction):
+        (WebKit::WebPage::performActionOnElement):
+
</ins><span class="cx"> 2014-02-01  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IDB: Implement IDBCursor.delete()
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.cpp        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -38,7 +38,9 @@
</span><span class="cx">     encoder &lt;&lt; nodeAtPositionIsAssistedNode;
</span><span class="cx">     encoder &lt;&lt; clickableElementName;
</span><span class="cx">     encoder &lt;&lt; url;
</span><ins>+    encoder &lt;&lt; title;
</ins><span class="cx">     encoder &lt;&lt; selectionRects;
</span><ins>+    encoder &lt;&lt; bounds;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool InteractionInformationAtPosition::decode(IPC::ArgumentDecoder&amp; decoder, InteractionInformationAtPosition&amp; result)
</span><span class="lines">@@ -55,9 +57,15 @@
</span><span class="cx">     if (!decoder.decode(result.url))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.title))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.selectionRects))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.bounds))
+        return false;
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedInteractionInformationAtPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/Shared/InteractionInformationAtPosition.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -44,7 +44,9 @@
</span><span class="cx">     bool nodeAtPositionIsAssistedNode;
</span><span class="cx">     String clickableElementName;
</span><span class="cx">     String url;
</span><ins>+    String title;
</ins><span class="cx">     Vector&lt;WebCore::SelectionRect&gt; selectionRects;
</span><ins>+    WebCore::IntRect bounds;
</ins><span class="cx"> 
</span><span class="cx">     void encode(IPC::ArgumentEncoder&amp;) const;
</span><span class="cx">     static bool decode(IPC::ArgumentDecoder&amp;, InteractionInformationAtPosition&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2SharediosWKGestureTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/Shared/ios/WKGestureTypes.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -64,6 +64,11 @@
</span><span class="cx">     WKGestureRecognizerStateRecognized = WKGestureRecognizerStateEnded
</span><span class="cx"> } WKGestureRecognizerState;
</span><span class="cx"> 
</span><ins>+typedef enum {
+    WKSheetActionCopy,
+    WKSheetActionSaveImage
+} WKSheetActions;
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // WKGestureTypes_h
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosPageClientImplIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -112,6 +112,7 @@
</span><span class="cx">     virtual void selectionDidChange() override;
</span><span class="cx">     virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&amp;, bool isCharEvent) override;
</span><span class="cx">     virtual void positionInformationDidChange(const InteractionInformationAtPosition&amp;);
</span><ins>+    virtual void saveImageToLibrary(PassRefPtr&lt;WebCore::SharedBuffer&gt;);
</ins><span class="cx"> 
</span><span class="cx">     // Auxiliary Client Creation
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.mm (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.mm        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -31,9 +31,11 @@
</span><span class="cx"> #import &quot;WKContentViewInternal.h&quot;
</span><span class="cx"> #import &quot;WebContextMenuProxy.h&quot;
</span><span class="cx"> #import &quot;WebEditCommandProxy.h&quot;
</span><ins>+#import &lt;UIKit/UIImagePickerController_Private.h&gt;
</ins><span class="cx"> #import &lt;UIKit/UIWebTouchEventsGestureRecognizer.h&gt;
</span><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><span class="cx"> #import &lt;WebCore/PlatformScreen.h&gt;
</span><ins>+#import &lt;WebCore/SharedBuffer.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> @interface UIView (IPI)
</span><span class="cx"> - (UIScrollView *)_scroller;
</span><span class="lines">@@ -207,6 +209,12 @@
</span><span class="cx">     [m_view _positionInformationDidChange:info];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PageClientImpl::saveImageToLibrary(PassRefPtr&lt;SharedBuffer&gt; imageBuffer)
+{
+    RetainPtr&lt;NSData&gt; imageData = imageBuffer-&gt;createNSData();
+    UIImageDataWriteToSavedPhotosAlbum(imageData.get(), nil, NULL, NULL);
+}
+
</ins><span class="cx"> bool PageClientImpl::executeSavedCommandBySelector(const String&amp;)
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKActionSheeth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.h (0 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -0,0 +1,83 @@
</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 &lt;UIKit/UIActionSheet.h&gt;
+#import &lt;UIKit/UIPopoverController.h&gt;
+#import &lt;WebKit2/WKDeclarationSpecifiers.h&gt;
+
+@protocol WKActionSheetDelegate;
+@class WKInteractionView;
+
+@interface WKActionSheet : UIActionSheet
+
+@property (nonatomic, assign) id &lt;WKActionSheetDelegate&gt; sheetDelegate;
+@property (nonatomic) UIPopoverArrowDirection arrowDirections;
+- (id)initWithView:(WKInteractionView *)view;
+- (void)doneWithSheet;
+- (BOOL)presentSheet;
+- (BOOL)presentSheetFromRect:(CGRect)presentationRect;
+- (void)updateSheetPosition;
+@end
+
+
+@protocol WKActionSheetDelegate&lt;UIActionSheetDelegate&gt;
+@required
+- (UIView *)hostViewForSheet;
+- (CGRect)initialPresentationRectInHostViewForSheet;
+- (CGRect)presentationRectInHostViewForSheet;
+@end
+
+// Elements to describe action sheet content.
+
+WK_EXPORT @interface WKElementActionInfo : NSObject
+
+- (WKElementActionInfo *)initWithInfo:(NSURL *)url location:(CGPoint)location title:(NSString *)title rect:(CGRect)rect;
+@property (nonatomic, readonly) CGPoint interactionLocation;
+@property (nonatomic, readonly) NSURL *url;
+@property (nonatomic, readonly) NSString *title;
+@property (nonatomic, readonly) CGRect boundingRect;
+@end
+
+typedef void (^WKElementActionHandler)(WKElementActionInfo *);
+typedef void (^WKElementActionHandlerInternal)(WKInteractionView *, WKElementActionInfo *);
+
+typedef enum {
+    WKElementActionTypeCustom = 0,
+    WKElementActionTypeOpen,
+    WKElementActionTypeCopy,
+    WKElementActionTypeSaveImage,
+    WKElementActionTypeAddToReadingList,
+} WKElementActionType;
+
+WK_EXPORT @interface WKElementAction : NSObject
+@property (nonatomic, readonly) WKElementActionType type;
+@property (nonatomic, readonly) NSString* title;
+
++ (WKElementAction *)customElementActionWithTitle:(NSString *)title actionHandler:(WKElementActionHandler)handler;
++ (WKElementAction *)standardElementActionWithType:(WKElementActionType)type;
++ (WKElementAction *)standardElementActionWithType:(WKElementActionType)type customTitle:(NSString *)title;
+- (void)runActionWithElementInfo:(WKElementActionInfo *)info view:(WKInteractionView *)view;
+
+@end
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKActionSheetmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.mm (0 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.mm                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheet.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -0,0 +1,298 @@
</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;WKActionSheet.h&quot;
+
+#import &quot;WKGestureTypes.h&quot;
+#import &quot;WKInteractionView.h&quot;
+#import &lt;SafariServices/SSReadingList.h&gt;
+#import &lt;UIKit/UIActionSheet_Private.h&gt;
+#import &lt;UIKit/UIView.h&gt;
+#import &lt;UIKit/UIWindow_Private.h&gt;
+#import &lt;WebCore/LocalizedStrings.h&gt;
+#import &lt;WebCore/SoftLinking.h&gt;
+#import &lt;wtf/text/WTFString.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+SOFT_LINK_FRAMEWORK(SafariServices);
+SOFT_LINK_CLASS(SafariServices, SSReadingList);
+
+@interface WKElementAction(Private)
+- (void)_runActionWithElement:(NSURL *)targetURL documentView:(WKInteractionView *)view interactionLocation:(CGPoint)interactionLocation;
+@end
+
+@implementation WKActionSheet {
+    id&lt;WKActionSheetDelegate&gt; _sheetDelegate;
+    id&lt;UIActionSheetDelegate&gt; _delegateWhileRotating;
+    WKInteractionView *_view;
+    UIPopoverArrowDirection _arrowDirections;
+    BOOL _isRotating;
+}
+
+- (id)initWithView:(WKInteractionView *)view
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    _arrowDirections = UIPopoverArrowDirectionAny;
+    _view = view;
+
+    if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) {
+        // Only iPads support popovers that rotate. UIActionSheets actually block rotation on iPhone/iPod Touch
+        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+        [center addObserver:self selector:@selector(willRotate) name:UIWindowWillRotateNotification object:nil];
+        [center addObserver:self selector:@selector(didRotate) name:UIWindowDidRotateNotification object:nil];
+    }
+
+    return self;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [NSObject cancelPreviousPerformRequestsWithTarget:self];
+
+    [super dealloc];
+}
+
+#pragma mark - Sheet presentation code
+
+- (BOOL)presentSheet
+{
+    // Calculate the presentation rect just before showing.
+    CGRect presentationRect = CGRectZero;
+    if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) {
+        presentationRect = [_sheetDelegate initialPresentationRectInHostViewForSheet];
+        if (CGRectIsEmpty(presentationRect))
+            return NO;
+    }
+
+    return [self presentSheetFromRect:presentationRect];
+}
+
+- (BOOL)presentSheetFromRect:(CGRect)presentationRect
+{
+    UIView *view = [_sheetDelegate hostViewForSheet];
+    if (!view)
+        return NO;
+
+    if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) {
+        [self presentFromRect:presentationRect
+                       inView:view
+                    direction:_arrowDirections
+    allowInteractionWithViews:nil
+              backgroundStyle:UIPopoverBackgroundStyleDefault
+                     animated:YES];
+    } else
+        [self showInView:view]; 
+
+    return YES;
+}
+
+- (void)doneWithSheet
+{
+    _delegateWhileRotating = nil;
+
+    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(didRotate) object:nil];
+}
+
+#pragma mark - Rotation handling code
+
+- (void)willRotate
+{
+    ASSERT(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
+
+    if (_isRotating)
+        return;
+
+    // Clear the delegate so that the method:
+    // - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
+    // is not called when the ActionSheet is dismissed below. Delegate is re-instated after rotation.
+    _delegateWhileRotating = [self delegate];
+    self.delegate = nil;
+    _isRotating = YES;
+
+    [self dismissWithClickedButtonIndex:[self cancelButtonIndex] animated:NO];
+}
+
+- (void)updateSheetPosition
+{
+    ASSERT(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
+
+    if (!_isRotating)
+        return;
+
+    _isRotating = NO;
+    
+    CGRect presentationRect = [_sheetDelegate presentationRectInHostViewForSheet];
+    if (!CGRectIsEmpty(presentationRect)) {
+        // Re-present the popover only if we are still pointing to content onscreen.
+        CGRect intersection = CGRectIntersection([[_sheetDelegate hostViewForSheet] bounds], presentationRect);
+        if (!CGRectIsEmpty(intersection)) {
+            self.delegate = _delegateWhileRotating;
+            [self presentSheetFromRect:intersection];
+            return;
+        }
+    }
+    
+    // Cancel the sheet as there is either no view or the content has now moved off screen.
+    [_delegateWhileRotating actionSheet:self clickedButtonAtIndex:[self cancelButtonIndex]];
+}
+
+- (void)didRotate
+{
+    ASSERT(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
+
+    [_view _updatePositionInformation];
+}
+
+@end
+
+@implementation WKElementActionInfo  {
+    CGPoint _interactionLocation;
+    NSURL *_url;
+    NSString *_title;
+    CGRect _boundingRect;
+    CGImageRef _snapshot;
+}
+
+- (WKElementActionInfo *) initWithInfo:(NSURL *)url location:(CGPoint)location title:(NSString *)title rect:(CGRect)rect
+{
+    _url = [url copy];
+    _interactionLocation = location;
+    _title = [title copy];
+    _boundingRect = rect;
+
+    return self;
+}
+
+- (void)dealloc
+{
+    [_title release];
+    [_url release];
+    
+    [super dealloc];
+}
+
+@end
+
+@implementation WKElementAction  {
+    NSString *_title;
+    WKElementActionHandlerInternal _actionHandler;
+    WKElementActionType _type;
+}
+
+- (id)initWithTitle:(NSString *)title actionHandler:(WKElementActionHandlerInternal)handler type:(WKElementActionType)type
+{
+    if (!(self = [super init]))
+        return nil;
+    _title = [title copy];
+    _type = type;
+    _actionHandler = Block_copy(handler);
+    return self;
+}
+
+- (void)dealloc
+{
+    [_title release];
+    [_actionHandler release];
+    [super dealloc];
+}
+
++ (WKElementAction *)customElementActionWithTitle:(NSString *)title actionHandler:(WKElementActionHandler)handler
+{
+    return [[[self alloc] initWithTitle:title
+                          actionHandler:^(WKInteractionView *view, WKElementActionInfo *actionInfo) { handler(actionInfo); }
+                                   type:WKElementActionTypeCustom] autorelease];
+}
+
+static void copyElement(WKInteractionView *view)
+{
+    [view _performAction:WebKit::WKSheetActionCopy];
+}
+
+static void saveImage(WKInteractionView *view)
+{
+    [view _performAction:WebKit::WKSheetActionSaveImage];
+}
+
+static void addToReadingList(NSURL *targetURL, NSString *title)
+{
+    if (!title || [title length] == 0)
+        title = [targetURL absoluteString];
+
+    [[getSSReadingListClass() defaultReadingList] addReadingListItemWithURL:targetURL title:title previewText:nil error:nil];
+}
+
++ (WKElementAction *)standardElementActionWithType:(WKElementActionType)type customTitle:(NSString *)customTitle
+{
+    NSString *title;
+    WKElementActionHandlerInternal handler;
+    switch (type) {
+    case WKElementActionTypeCopy:
+        title = WEB_UI_STRING_KEY(&quot;Copy&quot;, &quot;Copy ActionSheet Link&quot;, &quot;Title for Copy Link or Image action button&quot;);
+        handler = ^(WKInteractionView *view, WKElementActionInfo *actionInfo) {
+            copyElement(view);
+        };
+        break;
+    case WKElementActionTypeOpen:
+        title = WEB_UI_STRING_KEY(&quot;Open&quot;, &quot;Open ActionSheet Link&quot;, &quot;Title for Open Link action button&quot;);
+        handler = ^(WKInteractionView *view, WKElementActionInfo *actionInfo) {
+            [view _attemptClickAtLocation:actionInfo.interactionLocation];
+        };
+        break;
+    case WKElementActionTypeSaveImage:
+        title = WEB_UI_STRING_KEY(&quot;Save Image&quot;, &quot;Save Image&quot;, &quot;Title for Save Image action button&quot;);
+        handler = ^(WKInteractionView *view, WKElementActionInfo *actionInfo) {
+            saveImage(view);
+        };
+        break;
+    case WKElementActionTypeAddToReadingList:
+        title = WEB_UI_STRING(&quot;Add to Reading List&quot;, &quot;Title for Add to Reading List action button&quot;);
+        handler = ^(WKInteractionView *view, WKElementActionInfo *actionInfo) {
+            addToReadingList(actionInfo.url, actionInfo.title);
+        };
+        break;
+    default:
+        [NSException raise:NSInvalidArgumentException format:@&quot;There is no standard web element action of type %d.&quot;, type];
+        return nil;
+    }
+    return [[[WKElementAction alloc] initWithTitle:(customTitle ? customTitle : title) actionHandler:handler type:type] autorelease];
+}
+
++ (WKElementAction *)standardElementActionWithType:(WKElementActionType)type
+{
+    return [self standardElementActionWithType:type customTitle:nil];
+}
+
+- (void)runActionWithElementInfo:(WKElementActionInfo *)info view:(WKInteractionView *)view
+{
+    _actionHandler(view, info);
+}
+@end
+
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKActionSheetAssistanth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.h (0 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -0,0 +1,50 @@
</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;WKActionSheet.h&quot;
+
+#import &lt;UIKit/UIActionSheet.h&gt;
+#import &lt;UIKit/UIPopoverController.h&gt;
+#import &lt;WebKit2/WKDeclarationSpecifiers.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+@protocol WKActionSheetDelegate;
+@class WKInteractionView;
+
+namespace WebKit {
+class WebPageProxy;
+}
+
+@interface WKActionSheetAssistant : NSObject &lt;WKActionSheetDelegate&gt;
+
+- (id)initWithView:(WKInteractionView *)view;
+- (void)setPage:(PassRefPtr&lt;WebKit::WebPageProxy&gt;)page;
+- (void)showLinkSheet;
+- (void)showImageSheet;
+- (void)showDataDetectorsSheet;
+- (void)cleanupSheet;
+- (void)updateSheetPosition;
+@end
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKActionSheetAssistantmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.mm (0 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.mm                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKActionSheetAssistant.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -0,0 +1,341 @@
</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;WKActionSheetAssistant.h&quot;
+
+#import &quot;WKActionSheet.h&quot;
+#import &quot;WKInteractionView.h&quot;
+#import &quot;WebPageProxy.h&quot;
+#import &lt;TCC/TCC.h&gt;
+#import &lt;DataDetectorsUI/DDDetectionController.h&gt;
+#import &lt;SafariServices/SSReadingList.h&gt;
+#import &lt;UIKit/UIActionSheet_Private.h&gt;
+#import &lt;UIKit/UIView.h&gt;
+#import &lt;UIKit/UIViewController_Private.h&gt;
+#import &lt;UIKit/UIWindow_Private.h&gt;
+#import &lt;WebCore/LocalizedStrings.h&gt;
+#import &lt;WebCore/SoftLinking.h&gt;
+#import &lt;WebCore/WebCoreNSURLExtras.h&gt;
+#import &lt;wtf/text/WTFString.h&gt;
+
+SOFT_LINK_FRAMEWORK(SafariServices)
+SOFT_LINK_CLASS(SafariServices, SSReadingList)
+
+SOFT_LINK_PRIVATE_FRAMEWORK(TCC)
+SOFT_LINK(TCC, TCCAccessPreflight, TCCAccessPreflightResult, (CFStringRef service, CFDictionaryRef options), (service, options))
+SOFT_LINK_CONSTANT(TCC, kTCCServicePhotos, CFStringRef)
+
+SOFT_LINK_PRIVATE_FRAMEWORK(DataDetectorsUI)
+SOFT_LINK_CLASS(DataDetectorsUI, DDDetectionController)
+
+@interface WKElementAction(Private)
+- (void)_runActionWithElement:(NSURL *)targetURL documentView:(WKInteractionView *)view interactionLocation:(CGPoint)interactionLocation;
+@end
+
+@implementation WKActionSheetAssistant {
+    RetainPtr&lt;WKActionSheet&gt; _interactionSheet;
+    RefPtr&lt;WebKit::WebPageProxy&gt; _page;
+    RetainPtr&lt;NSArray&gt; _elementActions;
+    WKInteractionView *_view;
+}
+
+- (id)initWithView:(WKInteractionView *)view
+{
+    _view = view;
+    return self;
+}
+
+- (void)dealloc
+{
+    [self cleanupSheet];
+    _page = nullptr;
+    [super dealloc];
+}
+
+- (void)setPage:(PassRefPtr&lt;WebKit::WebPageProxy&gt;)page
+{
+    _page = page;
+}
+
+- (UIView *)superviewForSheet
+{
+    UIView *view = [_view window];
+
+    // FIXME: WebKit has a delegate to retrieve the superview for the image sheet (superviewForImageSheetForWebView)
+    // Do we need it in WK2?
+
+    // Find the top most view with a view controller
+    UIViewController *controller = nil;
+    UIView *currentView = _view;
+    while (currentView) {
+        UIViewController *aController = [UIViewController viewControllerForView:currentView];
+        if (aController)
+            controller = aController;
+
+        currentView = [currentView superview];
+    }
+    if (controller)
+        view = controller.view;
+
+    return view;
+}
+
+- (CGRect)_presentationRectForSheetGivenPoint:(CGPoint)point inHostView:(UIView *)hostView
+{
+    CGPoint presentationPoint = [hostView convertPoint:point fromView:_view];
+    CGRect presentationRect = CGRectMake(presentationPoint.x, presentationPoint.y, 1.0, 1.0);
+
+    return CGRectInset(presentationRect, -22.0, -22.0);
+}
+
+- (UIView *)hostViewForSheet
+{
+    return [self superviewForSheet];
+}
+
+- (CGRect)initialPresentationRectInHostViewForSheet
+{
+    UIView *view = [self superviewForSheet];
+    if (!view)
+        return CGRectZero;
+
+    return [self _presentationRectForSheetGivenPoint:_view.positionInformation.point inHostView:view];
+
+}
+
+- (CGRect)presentationRectInHostViewForSheet
+{
+    UIView *view = [self superviewForSheet];
+    if (!view)
+        return CGRectZero;
+
+    CGRect boundingRect = _view.positionInformation.bounds;
+    CGPoint fromPoint = _view.positionInformation.point;
+
+    // FIXME: We must adjust our presentation point to take into account a change in document scale.
+
+    // Test to see if we are still within the target node as it may have moved after rotation.
+    if (!CGRectContainsPoint(boundingRect, fromPoint))
+        fromPoint = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect));
+
+    return [self _presentationRectForSheetGivenPoint:fromPoint inHostView:view];
+}
+
+- (BOOL)presentSheet
+{
+    // Calculate the presentation rect just before showing.
+    CGRect presentationRect = CGRectZero;
+    if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) {
+        presentationRect = [self initialPresentationRectInHostViewForSheet];
+        if (CGRectIsEmpty(presentationRect))
+            return NO;
+    }
+
+    return [_interactionSheet presentSheetFromRect:presentationRect];
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    ASSERT(actionSheet == _interactionSheet);
+    if (actionSheet != _interactionSheet)
+        return;
+
+    if (_elementActions &amp;&amp; buttonIndex &lt; (NSInteger)[_elementActions count]) {
+        WKElementActionInfo* actionInfo = [[WKElementActionInfo alloc] initWithInfo:[NSURL URLWithString:_view.positionInformation.url]
+                                                                           location:_view.positionInformation.point
+                                                                              title:_view.positionInformation.title
+                                                                               rect:_view.positionInformation.bounds];
+        [[_elementActions objectAtIndex:buttonIndex] runActionWithElementInfo:actionInfo view:_view];
+        [actionInfo release];
+    }
+
+    [self cleanupSheet];
+}
+
+- (void)updateSheetPosition
+{
+    [_interactionSheet updateSheetPosition];
+}
+
+- (void)_createSheetWithElementActions:(NSArray *)actions showLinkTitle:(BOOL)showLinkTitle
+{
+    ASSERT(!_interactionSheet);
+
+    NSURL *targetURL = [NSURL URLWithString:_view.positionInformation.url];
+    NSString *urlScheme = [targetURL scheme];
+    BOOL isJavaScriptURL = [urlScheme length] &amp;&amp; [urlScheme caseInsensitiveCompare:@&quot;javascript&quot;] == NSOrderedSame;
+    // FIXME: We should check if Javascript is enabled in the preferences.
+
+    _interactionSheet = adoptNS([[WKActionSheet alloc] initWithView:_view]);
+    _interactionSheet.get().sheetDelegate = self;
+    _interactionSheet.get().actionSheetStyle = UIActionSheetStyleAutomatic;
+    _interactionSheet.get().delegate = self;
+
+    NSString *titleString = nil;
+    BOOL titleIsURL = NO;
+    if (showLinkTitle) {
+        if (isJavaScriptURL)
+            titleString = WEB_UI_STRING_KEY(&quot;JavaScript&quot;, &quot;JavaScript Action Sheet Title&quot;, &quot;Title for action sheet for JavaScript link&quot;);
+        else {
+            titleString = WebCore::userVisibleString(targetURL);
+            titleIsURL = YES;
+        }
+    } else
+        titleString = _view.positionInformation.title;
+
+    if ([titleString length]) {
+        [_interactionSheet setTitle:titleString];
+        if (titleIsURL) {
+            [[_interactionSheet _titleLabel] setLineBreakMode:NSLineBreakByTruncatingMiddle];
+            [_interactionSheet setTitleMaxLineCount:2];
+        } else
+            [[_interactionSheet _titleLabel] setLineBreakMode:NSLineBreakByTruncatingTail];
+    }
+
+    _elementActions = adoptNS([actions copy]);
+    for (WKElementAction *action in _elementActions.get())
+        [_interactionSheet addButtonWithTitle:[action title]];
+
+    [_interactionSheet setCancelButtonIndex:[_interactionSheet addButtonWithTitle:WEB_UI_STRING_KEY(&quot;Cancel&quot;, &quot;Cancel button label in button bar&quot;, &quot;Title for Cancel button label in button bar&quot;)]];
+    _page-&gt;startInteractionWithElementAtPosition(_view.positionInformation.point);
+}
+
+- (void)showImageSheet
+{
+    ASSERT(!_interactionSheet);
+
+    NSURL *targetURL = [NSURL URLWithString:_view.positionInformation.url];
+    NSMutableArray *actions = [NSMutableArray array];
+    if (!_view.positionInformation.url.isEmpty())
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeOpen]];
+    if ([getSSReadingListClass() supportsURL:targetURL])
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeAddToReadingList]];
+    if (TCCAccessPreflight(getkTCCServicePhotos(), NULL) != kTCCAccessPreflightDenied)
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeSaveImage]];
+    if (![[targetURL scheme] length] || [[targetURL scheme] caseInsensitiveCompare:@&quot;javascript&quot;] != NSOrderedSame)
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeCopy]];
+
+    // FIXME: Add call to delegate to add custom actions.
+
+    [self _createSheetWithElementActions:actions showLinkTitle:YES];
+    if (!_interactionSheet)
+        return;
+
+    if (![_interactionSheet presentSheet])
+        [self actionSheet:_interactionSheet.get() clickedButtonAtIndex:[_interactionSheet cancelButtonIndex]];
+}
+
+- (void)showLinkSheet
+{
+    ASSERT(!_interactionSheet);
+    NSURL *targetURL = [NSURL URLWithString:_view.positionInformation.url];
+    if (!targetURL)
+        return;
+
+    NSMutableArray *actions = [NSMutableArray array];
+    [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeOpen]];
+    if ([getSSReadingListClass() supportsURL:targetURL])
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeAddToReadingList]];
+    if (![[targetURL scheme] length] || [[targetURL scheme] caseInsensitiveCompare:@&quot;javascript&quot;] != NSOrderedSame)
+        [actions addObject:[WKElementAction standardElementActionWithType:WKElementActionTypeCopy]];
+
+    // FIXME: Add call to delegate to add custom actions.
+
+    [self _createSheetWithElementActions:actions showLinkTitle:YES];
+    if (!_interactionSheet)
+        return;
+
+    if (![_interactionSheet presentSheet])
+        [self actionSheet:_interactionSheet.get() clickedButtonAtIndex:[_interactionSheet cancelButtonIndex]];
+}
+
+- (void)showDataDetectorsSheet
+{
+    ASSERT(!_interactionSheet);
+    NSURL *targetURL = [NSURL URLWithString:_view.positionInformation.url];
+    if (!targetURL)
+        return;
+
+    if (![[getDDDetectionControllerClass() tapAndHoldSchemes] containsObject:[targetURL scheme]])
+        return;
+
+    // FIXME: This needs to be changed.
+    // We need a different API for DDDectectionController that doesn't take DOMNode and WebFrame objects.
+    // NSArray *dataDetectorsActions = [[getDDDetectionControllerClass() sharedController] actionsForDOMNode:_interaction.element forFrame:[_webView mainFrame]];
+    NSArray *dataDetectorsActions = nil;
+
+    // FIXME: The following condition will always be true for now, since there are no viable calls to retrieve
+    // data detector actions.
+    if ([dataDetectorsActions count] == 0)
+        return;
+
+    NSMutableArray *elementActions = [NSMutableArray array];
+    for (NSUInteger actionNumber = 0; actionNumber &lt; [dataDetectorsActions count]; actionNumber++) {
+        DDAction *action = [dataDetectorsActions objectAtIndex:actionNumber];
+        [elementActions addObject:[WKElementAction customElementActionWithTitle:[action localizedName] actionHandler:^(WKElementActionInfo *actionInfo) {
+            UIPopoverController *popoverController = nil;
+            if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) {
+                [_interactionSheet setUserInteractionEnabled:NO];
+                // &lt;rdar://problem/11015751&gt; Action sheet becomes black if a button is clicked twice on iPad
+                // prevent any further tap on the sheet while DD is loading its view controller, otherwise UIActionSheet goes amok
+
+                popoverController = [_interactionSheet _relinquishPopoverController];
+            }
+
+            [[getDDDetectionControllerClass() sharedController] performAction:action
+                                                                       inView:[self superviewForSheet]
+                                                        withPopoverController:popoverController
+                                                          interactionDelegate:self];
+        }]];
+    }
+
+    [self _createSheetWithElementActions:elementActions showLinkTitle:NO];
+    if (!_interactionSheet)
+        return;
+
+    // The implicit second button is &quot;cancel&quot;, which is swallowed by the popover at presentation time.
+    if (_interactionSheet.get().numberOfButtons &lt;= 2)
+        _interactionSheet.get().arrowDirections = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown;
+
+    if (![_interactionSheet presentSheet])
+        [self actionSheet:_interactionSheet.get() clickedButtonAtIndex:[_interactionSheet cancelButtonIndex]];
+}
+
+- (void)cleanupSheet
+{
+    _page-&gt;stopInteraction();
+
+    [_interactionSheet doneWithSheet];
+    [_interactionSheet setSheetDelegate:nil];
+    [_interactionSheet setDelegate:nil];
+    _interactionSheet = nil;
+
+    _elementActions = nil;
+}
+
+@end
+
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKInteractionViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><ins>+#import &quot;WKGestureTypes.h&quot;
</ins><span class="cx"> #import &lt;UIKit/UIWebFormAccessory.h&gt;
</span><span class="cx"> #import &lt;UIKit/UITextInput_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIView.h&gt;
</span><span class="lines">@@ -59,4 +60,9 @@
</span><span class="cx"> - (void)_selectionChanged;
</span><span class="cx"> - (BOOL)_interpretKeyEvent:(WebIOSEvent *)theEvent isCharEvent:(BOOL)isCharEvent;
</span><span class="cx"> - (void)_positionInformationDidChange:(const WebKit::InteractionInformationAtPosition&amp;)info;
</span><ins>+- (void)_attemptClickAtLocation:(CGPoint)location;
+- (void)_updatePositionInformation;
+- (void)_performAction:(WebKit::WKSheetActions)action;
+
+@property (readonly, nonatomic) WebKit::InteractionInformationAtPosition positionInformation;
</ins><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIiosWKInteractionViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKInteractionView.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -29,12 +29,14 @@
</span><span class="cx"> #import &quot;InteractionInformationAtPosition.h&quot;
</span><span class="cx"> #import &quot;NativeWebKeyboardEvent.h&quot;
</span><span class="cx"> #import &quot;NativeWebTouchEvent.h&quot;
</span><ins>+#import &quot;WKActionSheetAssistant.h&quot;
</ins><span class="cx"> #import &quot;WKBase.h&quot;
</span><span class="cx"> #import &quot;WKGestureTypes.h&quot;
</span><span class="cx"> #import &quot;WebEvent.h&quot;
</span><span class="cx"> #import &quot;WebIOSEventFactory.h&quot;
</span><span class="cx"> #import &quot;WebPageMessages.h&quot;
</span><span class="cx"> #import &quot;WebProcessProxy.h&quot;
</span><ins>+#import &lt;DataDetectorsUI/DDDetectionController.h&gt;
</ins><span class="cx"> #import &lt;UIKit/UIFont_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIGestureRecognizer_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIKeyboardImpl.h&gt;
</span><span class="lines">@@ -48,10 +50,15 @@
</span><span class="cx"> #import &lt;WebCore/Color.h&gt;
</span><span class="cx"> #import &lt;WebCore/FloatQuad.h&gt;
</span><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><ins>+#import &lt;WebCore/SoftLinking.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebEvent.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebSelectionRect.h&gt;
</span><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><ins>+#import &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><ins>+SOFT_LINK_PRIVATE_FRAMEWORK(DataDetectorsUI)
+SOFT_LINK_CLASS(DataDetectorsUI, DDDetectionController)
+
</ins><span class="cx"> using namespace WebCore;
</span><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><span class="lines">@@ -167,6 +174,7 @@
</span><span class="cx">     RetainPtr&lt;NSString&gt; _markedText;
</span><span class="cx">     InteractionInformationAtPosition _positionInformation;
</span><span class="cx">     BOOL _hasValidPositionInformation;
</span><ins>+    RetainPtr&lt;WKActionSheetAssistant&gt; _actionSheetAssistant;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @synthesize inputDelegate = _inputDelegate;
</span><span class="lines">@@ -213,6 +221,7 @@
</span><span class="cx">     // FIXME: This should be called when we get notified that loading has completed.
</span><span class="cx">     [self useSelectionAssistantWithMode:UIWebSelectionModeWeb];
</span><span class="cx"> 
</span><ins>+    _actionSheetAssistant = adoptNS([[WKActionSheetAssistant alloc] initWithView:self]);
</ins><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -220,6 +229,7 @@
</span><span class="cx"> {
</span><span class="cx">     _webSelectionAssistant = nil;
</span><span class="cx">     _textSelectionAssistant = nil;
</span><ins>+    _actionSheetAssistant = nil;
</ins><span class="cx">     [_touchEventGestureRecognizer setDelegate:nil];
</span><span class="cx">     [_singleTapGestureRecognizer setDelegate:nil];
</span><span class="cx">     [_doubleTapGestureRecognizer setDelegate:nil];
</span><span class="lines">@@ -239,6 +249,7 @@
</span><span class="cx"> - (void)setPage:(PassRefPtr&lt;WebKit::WebPageProxy&gt;)page
</span><span class="cx"> {
</span><span class="cx">     _page = page;
</span><ins>+    [_actionSheetAssistant setPage:_page];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)isEditable
</span><span class="lines">@@ -418,22 +429,29 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_showImageSheet
</span><span class="cx"> {
</span><del>-
</del><ins>+    [_actionSheetAssistant showImageSheet];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_showLinkSheet
</span><span class="cx"> {
</span><ins>+    [_actionSheetAssistant showLinkSheet];
+}
</ins><span class="cx"> 
</span><ins>+- (void)_showDataDetectorsSheet
+{
+    [_actionSheetAssistant showDataDetectorsSheet];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (SEL)_actionForLongPress
</span><span class="cx"> {
</span><span class="cx">     if (_positionInformation.clickableElementName == &quot;IMG&quot;)
</span><span class="cx">         return @selector(_showImageSheet);
</span><del>-    else if (_positionInformation.clickableElementName == &quot;A&quot;)
</del><ins>+    else if (_positionInformation.clickableElementName == &quot;A&quot;) {
+        NSURL *targetURL = [NSURL URLWithString:_positionInformation.url];
+        if ([[getDDDetectionControllerClass() tapAndHoldSchemes] containsObject:[targetURL scheme]])
+            return @selector(_showDataDetectorsSheet);
</ins><span class="cx">         return @selector(_showLinkSheet);
</span><del>-    // FIXME: Add check for links and datadetectors.
-
</del><ins>+    }
</ins><span class="cx">     return nil;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -445,6 +463,12 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_updatePositionInformation
+{
+    _hasValidPositionInformation = NO;
+    _page-&gt;requestPositionInformation(_positionInformation.point);
+}
+
</ins><span class="cx"> - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
</span><span class="cx"> {
</span><span class="cx">     CGPoint point = [gestureRecognizer locationInView:self];
</span><span class="lines">@@ -573,18 +597,10 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(gestureRecognizer == _longPressGestureRecognizer);
</span><span class="cx"> 
</span><del>-    switch ([gestureRecognizer state]) {
-    case UIGestureRecognizerStateBegan:
-        // FIXME: add implementation
-        break;
-    case UIGestureRecognizerStateEnded:
-        // FIXME: add implementation
-        break;
-    case UIGestureRecognizerStateCancelled:
-        // FIXME: add implementation
-        break;
-    default:
-        break;
</del><ins>+    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
+        SEL action = [self _actionForLongPress];
+        if (action)
+            [self performSelector:action];
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -655,6 +671,8 @@
</span><span class="cx"> {
</span><span class="cx">     _positionInformation = info;
</span><span class="cx">     _hasValidPositionInformation = YES;
</span><ins>+    if (_actionSheetAssistant)
+        [_actionSheetAssistant updateSheetPosition];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (UIView *)inputAccessoryView
</span><span class="lines">@@ -793,6 +811,11 @@
</span><span class="cx">     [_textSelectionAssistant hideTextStyleOptions];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_performAction:(WKSheetActions)action
+{
+    _page-&gt;performActionOnElement((uint32_t)action);
+}
+
</ins><span class="cx"> - (void)copy:(id)sender
</span><span class="cx"> {
</span><span class="cx">     _page-&gt;executeEditCommand(ASCIILiteral(&quot;copy&quot;));
</span><span class="lines">@@ -1191,7 +1214,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_updateAccessory
</span><span class="cx"> {
</span><del>-    // FIXME: need to initialize with valus from the WebProcess.
</del><ins>+    // FIXME: We need to initialize with values from the WebProcess.
</ins><span class="cx">     _accessory.nextEnabled = YES;
</span><span class="cx">     _accessory.previousEnabled = YES;
</span><span class="cx">     
</span><span class="lines">@@ -1425,8 +1448,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-/* Modify text without starting a new undo grouping.
- */
</del><ins>+// Modify text without starting a new undo grouping.
</ins><span class="cx"> - (void)replaceRangeWithTextWithoutClosingTyping:(UITextRange *)range replacementText:(NSString *)text
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -249,6 +249,7 @@
</span><span class="cx">     virtual void selectionDidChange() = 0;
</span><span class="cx">     virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&amp;, bool isCharEvent) = 0;
</span><span class="cx">     virtual void positionInformationDidChange(const InteractionInformationAtPosition&amp;) = 0;
</span><ins>+    virtual void saveImageToLibrary(PassRefPtr&lt;WebCore::SharedBuffer&gt;) = 0;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Auxiliary Client Creation
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -449,6 +449,10 @@
</span><span class="cx">     void didReceivePositionInformation(const InteractionInformationAtPosition&amp;);
</span><span class="cx">     void getPositionInformation(const WebCore::IntPoint&amp;, InteractionInformationAtPosition&amp;);
</span><span class="cx">     void requestPositionInformation(const WebCore::IntPoint&amp;);
</span><ins>+    void startInteractionWithElementAtPosition(const WebCore::IntPoint&amp;);
+    void stopInteraction();
+    void performActionOnElement(uint32_t action);
+    void saveImageToLibrary(const SharedMemory::Handle&amp; imageHandle, uint64_t imageSize);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     const EditorState&amp; editorState() const { return m_editorState; }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -157,6 +157,7 @@
</span><span class="cx">     AutocorrectionContextCallback(String beforeText, String markedText, String selectedText, String afterText, uint64_t location, uint64_t length, uint64_t callbackID)
</span><span class="cx">     InterpretKeyEvent(WebKit::EditorState state, bool isCharEvent) -&gt; (bool handled)
</span><span class="cx">     DidReceivePositionInformation(WebKit::InteractionInformationAtPosition information)
</span><ins>+    SaveImageToLibrary(WebKit::SharedMemory::Handle handle, uint64_t size)
</ins><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="cx">     PrintFinishedCallback(WebCore::ResourceError error, uint64_t callbackID)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -321,6 +321,28 @@
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::RequestPositionInformation(point), m_pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::startInteractionWithElementAtPosition(const WebCore::IntPoint&amp; point)
+{
+    m_process-&gt;send(Messages::WebPage::StartInteractionWithElementAtPosition(point), m_pageID);
+}
+
+void WebPageProxy::stopInteraction()
+{
+    m_process-&gt;send(Messages::WebPage::StopInteraction(), m_pageID);
+}
+
+void WebPageProxy::performActionOnElement(uint32_t action)
+{
+    m_process-&gt;send(Messages::WebPage::PerformActionOnElement(action), m_pageID);
+}
+
+void WebPageProxy::saveImageToLibrary(const SharedMemory::Handle&amp; imageHandle, uint64_t imageSize)
+{
+    RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(imageHandle, SharedMemory::ReadOnly);
+    RefPtr&lt;SharedBuffer&gt; buffer = SharedBuffer::create(static_cast&lt;unsigned char*&gt;(sharedMemoryBuffer-&gt;data()), imageSize);
+    m_pageClient.saveImageToLibrary(buffer);
+}
+
</ins><span class="cx"> void WebPageProxy::notifyRevealedSelection()
</span><span class="cx"> {
</span><span class="cx">     m_pageClient.selectionDidChange();
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -1327,6 +1327,10 @@
</span><span class="cx">                 C0E3AA7C1209E83C00A49D01 /* Module.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E3AA441209E2BA00A49D01 /* Module.h */; };
</span><span class="cx">                 C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */ = {isa = PBXBuildFile; fileRef = C517388012DF8F4F00EE3F47 /* DragControllerAction.h */; };
</span><span class="cx">                 C5237F6012441CA300780472 /* WebEditorClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C5237F5F12441CA300780472 /* WebEditorClientMac.mm */; };
</span><ins>+                C5245391189C6B85003DF476 /* WKActionSheetAssistant.h in Headers */ = {isa = PBXBuildFile; fileRef = C524538F189C6B85003DF476 /* WKActionSheetAssistant.h */; };
+                C5245392189C6B85003DF476 /* WKActionSheetAssistant.mm in Sources */ = {isa = PBXBuildFile; fileRef = C5245390189C6B85003DF476 /* WKActionSheetAssistant.mm */; };
+                C535BD5918919CFC0098F1F5 /* WKActionSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = C535BD5718919CFC0098F1F5 /* WKActionSheet.h */; };
+                C535BD5A18919CFC0098F1F5 /* WKActionSheet.mm in Sources */ = {isa = PBXBuildFile; fileRef = C535BD5818919CFC0098F1F5 /* WKActionSheet.mm */; };
</ins><span class="cx">                 C574A37712E6099D002DFE98 /* WebDragClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C554FFA212E4E8EA002F22C0 /* WebDragClientMac.mm */; };
</span><span class="cx">                 C574A58112E66681002DFE98 /* PasteboardTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = C574A57F12E66681002DFE98 /* PasteboardTypes.h */; };
</span><span class="cx">                 C574A58212E66681002DFE98 /* PasteboardTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = C574A58012E66681002DFE98 /* PasteboardTypes.mm */; };
</span><span class="lines">@@ -3081,6 +3085,10 @@
</span><span class="cx">                 C0E3AA481209E45000A49D01 /* ModuleMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ModuleMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C517388012DF8F4F00EE3F47 /* DragControllerAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragControllerAction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C5237F5F12441CA300780472 /* WebEditorClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebEditorClientMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                C524538F189C6B85003DF476 /* WKActionSheetAssistant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKActionSheetAssistant.h; path = ios/WKActionSheetAssistant.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C5245390189C6B85003DF476 /* WKActionSheetAssistant.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKActionSheetAssistant.mm; path = ios/WKActionSheetAssistant.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C535BD5718919CFC0098F1F5 /* WKActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKActionSheet.h; path = ios/WKActionSheet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C535BD5818919CFC0098F1F5 /* WKActionSheet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKActionSheet.mm; path = ios/WKActionSheet.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 C554FFA212E4E8EA002F22C0 /* WebDragClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebDragClientMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C574A57F12E66681002DFE98 /* PasteboardTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasteboardTypes.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C574A58012E66681002DFE98 /* PasteboardTypes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardTypes.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4120,6 +4128,10 @@
</span><span class="cx">                                 2DA944791884E3B500ED86DB /* PageClientImplIOS.mm */,
</span><span class="cx">                                 2DA9447A1884E3B500ED86DB /* UIWKRemoteView.h */,
</span><span class="cx">                                 2DA9447B1884E3B500ED86DB /* UIWKRemoteView.mm */,
</span><ins>+                                C535BD5718919CFC0098F1F5 /* WKActionSheet.h */,
+                                C535BD5818919CFC0098F1F5 /* WKActionSheet.mm */,
+                                C524538F189C6B85003DF476 /* WKActionSheetAssistant.h */,
+                                C5245390189C6B85003DF476 /* WKActionSheetAssistant.mm */,
</ins><span class="cx">                                 2DA9447C1884E3B500ED86DB /* WKContentView.h */,
</span><span class="cx">                                 2DA9447D1884E3B500ED86DB /* WKContentView.mm */,
</span><span class="cx">                                 2DA9447E1884E3B500ED86DB /* WKContentViewInternal.h */,
</span><span class="lines">@@ -6450,6 +6462,7 @@
</span><span class="cx">                                 1AB8A1F418400B8F00E9AE69 /* WKPageFindClient.h in Headers */,
</span><span class="cx">                                 75E749EA180DBB9800088BA6 /* WebOriginDataManagerMessages.h in Headers */,
</span><span class="cx">                                 2DA944931884E3B500ED86DB /* WKScrollView.h in Headers */,
</span><ins>+                                C535BD5918919CFC0098F1F5 /* WKActionSheet.h in Headers */,
</ins><span class="cx">                                 51ACBBA0127A8F2C00D203B9 /* WebContextMenuProxyMac.h in Headers */,
</span><span class="cx">                                 BCCB75C61203A1CE00222D1B /* WebContextMessageKinds.h in Headers */,
</span><span class="cx">                                 BCEE7D0E12846F69009827DA /* WebContextMessages.h in Headers */,
</span><span class="lines">@@ -6779,6 +6792,7 @@
</span><span class="cx">                                 BC8699B7116AADAA002A925B /* WKViewInternal.h in Headers */,
</span><span class="cx">                                 BFA6179F12F0B99D0033E0CA /* WKViewPrivate.h in Headers */,
</span><span class="cx">                                 755422CC180773CE0046F6A8 /* WebOriginDataManager.h in Headers */,
</span><ins>+                                C5245391189C6B85003DF476 /* WKActionSheetAssistant.h in Headers */,
</ins><span class="cx">                                 C5E1AFE916B20B75006CC1F2 /* WKWebArchive.h in Headers */,
</span><span class="cx">                                 C5E1AFEB16B20B7E006CC1F2 /* WKWebArchiveResource.h in Headers */,
</span><span class="cx">                                 BC989D82161A7E5D000D46D3 /* WKWebProcessPlugIn.h in Headers */,
</span><span class="lines">@@ -7784,6 +7798,7 @@
</span><span class="cx">                                 1AD3306E16B1D991004F60E7 /* StorageAreaImpl.cpp in Sources */,
</span><span class="cx">                                 1ACECD2417162DB1001FC9EF /* StorageAreaMap.cpp in Sources */,
</span><span class="cx">                                 1A334DED16DE8F88006A8E38 /* StorageAreaMapMessageReceiver.cpp in Sources */,
</span><ins>+                                C535BD5A18919CFC0098F1F5 /* WKActionSheet.mm in Sources */,
</ins><span class="cx">                                 1A44B95B16B73F9F00B7BBD8 /* StorageManager.cpp in Sources */,
</span><span class="cx">                                 1AB31A9616BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 1A44B95716B737AA00B7BBD8 /* StorageNamespaceImpl.cpp in Sources */,
</span><span class="lines">@@ -7960,6 +7975,7 @@
</span><span class="cx">                                 2DA944A11884E4F000ED86DB /* WebIOSEventFactory.mm in Sources */,
</span><span class="cx">                                 BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 1A3E736211CC2659007BD539 /* WebPlatformStrategies.cpp in Sources */,
</span><ins>+                                C5245392189C6B85003DF476 /* WKActionSheetAssistant.mm in Sources */,
</ins><span class="cx">                                 C0337DDD127A521C008FF4F4 /* WebPlatformTouchPoint.cpp in Sources */,
</span><span class="cx">                                 51D0D436183B353D0097041D /* DatabaseProcessIDBConnectionMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 31D5929E166E060000E6BF02 /* WebPlugInClient.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -430,6 +430,9 @@
</span><span class="cx">     void confirmComposition();
</span><span class="cx">     void getPositionInformation(const WebCore::IntPoint&amp;, InteractionInformationAtPosition&amp;);
</span><span class="cx">     void requestPositionInformation(const WebCore::IntPoint&amp;);
</span><ins>+    void startInteractionWithElementAtPosition(const WebCore::IntPoint&amp;);
+    void stopInteraction();
+    void performActionOnElement(uint32_t action);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     NotificationPermissionRequestManager* notificationPermissionRequestManager();
</span><span class="lines">@@ -1041,6 +1044,7 @@
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     RefPtr&lt;WebCore::Node&gt; m_assistedNode;
</span><span class="cx">     RefPtr&lt;WebCore::Range&gt; m_currentWordRange;
</span><ins>+    RefPtr&lt;WebCore::Node&gt; m_interactionNode;
</ins><span class="cx">     bool m_shouldReturnWordAtSelection;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -57,6 +57,9 @@
</span><span class="cx">     ConfirmComposition()
</span><span class="cx">     GetPositionInformation(WebCore::IntPoint point) -&gt; (WebKit::InteractionInformationAtPosition information)
</span><span class="cx">     RequestPositionInformation(WebCore::IntPoint point)
</span><ins>+    StartInteractionWithElementAtPosition(WebCore::IntPoint point)
+    StopInteraction()
+    PerformActionOnElement(uint32_t action)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (163254 => 163255)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-02-02 02:25:13 UTC (rev 163254)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-02-02 02:37:43 UTC (rev 163255)
</span><span class="lines">@@ -44,13 +44,16 @@
</span><span class="cx"> #import &lt;WebCore/FrameView.h&gt;
</span><span class="cx"> #import &lt;WebCore/HitTestResult.h&gt;
</span><span class="cx"> #import &lt;WebCore/HTMLElementTypeHelpers.h&gt;
</span><ins>+#import &lt;WebCore/HTMLParserIdioms.h&gt;
</ins><span class="cx"> #import &lt;WebCore/MainFrame.h&gt;
</span><span class="cx"> #import &lt;WebCore/Node.h&gt;
</span><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><span class="cx"> #import &lt;WebCore/Page.h&gt;
</span><ins>+#import &lt;WebCore/Pasteboard.h&gt;
</ins><span class="cx"> #import &lt;WebCore/PlatformKeyboardEvent.h&gt;
</span><span class="cx"> #import &lt;WebCore/PlatformMouseEvent.h&gt;
</span><span class="cx"> #import &lt;WebCore/RenderImage.h&gt;
</span><ins>+#import &lt;WebCore/ResourceBuffer.h&gt;
</ins><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextIterator.h&gt;
</span><span class="cx"> #import &lt;WebCore/VisibleUnits.h&gt;
</span><span class="lines">@@ -809,6 +812,14 @@
</span><span class="cx">     computeAutocorrectionContext(m_page-&gt;focusController().focusedOrMainFrame(), contextBefore, markedText, selectedText, contextAfter, location, length);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static Element* containingLinkElement(Element* element)
+{
+    for (Element* currentElement = element; currentElement; currentElement = currentElement-&gt;parentElement())
+        if (currentElement-&gt;isLink())
+            return currentElement;
+    return 0;
+}
+
</ins><span class="cx"> void WebPage::getPositionInformation(const IntPoint&amp; point, InteractionInformationAtPosition&amp; info)
</span><span class="cx"> {
</span><span class="cx">     FloatPoint adjustedPoint;
</span><span class="lines">@@ -819,16 +830,20 @@
</span><span class="cx">     if (hitNode) {
</span><span class="cx">         info.clickableElementName = hitNode-&gt;nodeName();
</span><span class="cx"> 
</span><del>-        const HTMLElement* element = toHTMLElement(hitNode);
</del><ins>+        Element* element = hitNode-&gt;isElementNode() ? toElement(hitNode) : 0;
</ins><span class="cx">         if (!element)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         if (element-&gt;renderer() &amp;&amp; element-&gt;renderer()-&gt;isRenderImage()) {
</span><del>-            URL url = toRenderImage(element-&gt;renderer())-&gt;cachedImage()-&gt;url();
-            if (!url.string().isNull())
-                info.url = url.string();
</del><ins>+            Element* linkElement = containingLinkElement(element);
+
+            if (linkElement)
+                info.url = linkElement-&gt;document().completeURL(stripLeadingAndTrailingHTMLSpaces(linkElement-&gt;getAttribute(HTMLNames::hrefAttr)));;
</ins><span class="cx">         } else if (element-&gt;isLink())
</span><del>-            info.url = element-&gt;getAttribute(HTMLNames::hrefAttr).string();
</del><ins>+            info.url = element-&gt;document().completeURL(stripLeadingAndTrailingHTMLSpaces(element-&gt;getAttribute(HTMLNames::hrefAttr)));
+        info.title = element-&gt;getAttribute(HTMLNames::titleAttr).string();
+        if (element-&gt;renderer())
+            info.bounds = element-&gt;renderer()-&gt;absoluteBoundingBoxRect(true);
</ins><span class="cx">     } else {
</span><span class="cx">         Frame&amp; frame = m_page-&gt;mainFrame();
</span><span class="cx">         hitNode = frame.eventHandler().hitTestResultAtPoint((point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent).innerNode();
</span><span class="lines">@@ -852,6 +867,55 @@
</span><span class="cx">     send(Messages::WebPageProxy::DidReceivePositionInformation(info));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::startInteractionWithElementAtPosition(const WebCore::IntPoint&amp; point)
+{
+    FloatPoint adjustedPoint;
+    m_interactionNode = m_page-&gt;mainFrame().nodeRespondingToClickEvents(point, adjustedPoint);
+}
+
+void WebPage::stopInteraction()
+{
+    m_interactionNode = nullptr;
+}
+
+void WebPage::performActionOnElement(uint32_t action)
+{
+    if (!m_interactionNode || !m_interactionNode-&gt;isHTMLElement())
+        return;
+
+    HTMLElement* element = toHTMLElement(m_interactionNode.get());
+    if (!element-&gt;renderer())
+        return;
+
+    if (static_cast&lt;WKSheetActions&gt;(action) == WKSheetActionCopy) {
+        if (element-&gt;renderer()-&gt;isRenderImage()) {
+            Element* linkElement = containingLinkElement(element);
+        
+            if (!linkElement)
+                m_interactionNode-&gt;document().frame()-&gt;editor().writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *element, toRenderImage(element-&gt;renderer())-&gt;cachedImage()-&gt;url(), String());
+            else
+                m_interactionNode-&gt;document().frame()-&gt;editor().copyURL(linkElement-&gt;document().completeURL(stripLeadingAndTrailingHTMLSpaces(linkElement-&gt;getAttribute(HTMLNames::hrefAttr))), linkElement-&gt;textContent());
+        } else if (element-&gt;isLink()) {
+            m_interactionNode-&gt;document().frame()-&gt;editor().copyURL(element-&gt;document().completeURL(stripLeadingAndTrailingHTMLSpaces(element-&gt;getAttribute(HTMLNames::hrefAttr))), element-&gt;textContent());
+        }
+    } else if (static_cast&lt;WKSelectionTouch&gt;(action) == WKSheetActionSaveImage) {
+        if (!element-&gt;renderer()-&gt;isRenderImage())
+            return;
+        CachedImage* cachedImage = toRenderImage(element-&gt;renderer())-&gt;cachedImage();
+        if (cachedImage) {
+            SharedMemory::Handle handle;
+            RefPtr&lt;SharedBuffer&gt; buffer = cachedImage-&gt;resourceBuffer()-&gt;sharedBuffer();
+            if (buffer) {
+                uint64_t bufferSize = buffer-&gt;size();
+                RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(bufferSize);
+                memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), bufferSize);
+                sharedMemoryBuffer-&gt;createHandle(handle, SharedMemory::ReadOnly);
+                send(Messages::WebPageProxy::SaveImageToLibrary(handle, bufferSize));
+            }
+        }
+    }
+}
+
</ins><span class="cx"> void WebPage::elementDidFocus(WebCore::Node* node)
</span><span class="cx"> {
</span><span class="cx">     m_assistedNode = node;
</span></span></pre>
</div>
</div>

</body>
</html>