<!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>[168180] 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/168180">168180</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2014-05-02 12:28:30 -0700 (Fri, 02 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] WebKit2 File Upload Support
https://bugs.webkit.org/show_bug.cgi?id=132024

Reviewed by Enrica Casucci.

Source/WebCore:
* English.lproj/Localizable.strings:
New localized strings for &lt;input type=&quot;file&quot;&gt; on iOS.

Source/WebKit2:
* Configurations/WebKit2.xcconfig:
Include MobileCoreServices on iOS for kUTTypeImage/kUTTypeMovie.

* WebKit2.xcodeproj/project.pbxproj:
Add new files.

* UIProcess/WebOpenPanelResultListenerProxy.h:
* UIProcess/WebOpenPanelResultListenerProxy.cpp:
(WebKit::filePathsFromFileURLs):
(WebKit::WebOpenPanelResultListenerProxy::chooseFiles):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::runOpenPanel):
(WebKit::WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon):
* WebProcess/WebPage/WebOpenPanelResultListener.h:
* WebProcess/WebPage/WebOpenPanelResultListener.cpp:
(WebKit::WebOpenPanelResultListener::didChooseFilesWithDisplayStringAndIcon):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon):
Message forwarding for choosing files and providing a display string and icon,
leading down to the existing WebCore FileChooser method.

* UIProcess/PageClient.h:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::handleRunOpenPanel):
Add a default handler for file open panel on iOS.
Forwards to the content view.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView lastInteractionLocation]):
(-[WKContentView _webTouchEventsRecognized:]):
(-[WKContentView _highlightLongPressRecognized:]):
(-[WKContentView _longPressRecognized:]):
(-[WKContentView _singleTapRecognized:]):
(-[WKContentView _doubleTapRecognized:]):
(-[WKContentView _twoFingerDoubleTapRecognized:]):
Keep track of the last interaction location. This matches previous behavior
of showing the file upload popover where the user tapped, to handle
cases where the &lt;input&gt; is hidden.

(-[WKContentView _showRunOpenPanel:resultListener:]):
(-[WKContentView fileUploadPanelDidDismiss:]):
Handle showing the cleaning up after the file upload panel.

* UIProcess/ios/forms/WKFileUploadPanel.h:
* UIProcess/ios/forms/WKFileUploadPanel.mm: Added.
(squareCropRectForSize):
(squareImage):
(thumbnailSizedImageForImage):
(-[_WKFileUploadItem isVideo]):
(-[_WKFileUploadItem fileURL]):
(-[_WKFileUploadItem displayImage]):
(-[_WKImageFileUploadItem initWithFilePath:originalImage:]):
(-[_WKImageFileUploadItem isVideo]):
(-[_WKImageFileUploadItem fileURL]):
(-[_WKImageFileUploadItem displayImage]):
(-[_WKVideoFileUploadItem initWithFilePath:mediaURL:]):
(-[_WKVideoFileUploadItem isVideo]):
(-[_WKVideoFileUploadItem fileURL]):
(-[_WKVideoFileUploadItem displayImage]):
Helper class for each image picker selection. Knows how to get
a file URL and thumbnail display image for the item.

(-[WKFileUploadPanel initWithView:]):
(-[WKFileUploadPanel dealloc]):
(-[WKFileUploadPanel _dispatchDidDismiss]):
(-[WKFileUploadPanel _cancel]):
(-[WKFileUploadPanel _chooseFiles:displayString:iconImage:]):
Lifetime of the upload panel requires that either cancel or choose
must happen as we go through the file picking process.

(-[WKFileUploadPanel presentWithParameters:WebKit::resultListener:WebKit::]):
(-[WKFileUploadPanel dismiss]):
API to show or dismiss the panel.

(-[WKFileUploadPanel _dismissDisplayAnimated:]):
Helper to clean up the UI as it progresses or completes no matter the device idiom.

(-[WKFileUploadPanel _presentPopoverWithContentViewController:animated:]):
(-[WKFileUploadPanel _presentFullscreenViewController:animated:]):
UI presentation for the appropriate idiom.

(-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
(-[WKFileUploadPanel _showMediaSourceSelectionSheet]):
(-[WKFileUploadPanel _showPhotoPickerWithSourceType:]):
Showing the action sheet or image picker.

(-[WKFileUploadPanel popoverControllerDidDismissPopover:]):
(-[WKFileUploadPanel _willMultipleSelectionDelegateBeCalled]):
(-[WKFileUploadPanel imagePickerController:didFinishPickingMediaWithInfo:]):
(-[WKFileUploadPanel imagePickerController:didFinishPickingMultipleMediaWithInfo:]):
(-[WKFileUploadPanel imagePickerControllerDidCancel:]):
Action sheet or image picker handlers.

(-[WKFileUploadPanel _processMediaInfoDictionaries:successBlock:failureBlock:]):
(-[WKFileUploadPanel _processMediaInfoDictionaries:atIndex:processedResults:processedImageCount:processedVideoCount:successBlock:failureBlock:]):
(-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):
(-[WKFileUploadPanel _displayStringForPhotos:videos:]):
Processing selections from the image picker to FileUploadItems.</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="#trunkSourceWebKit2ConfigurationsWebKit2xcconfig">trunk/Source/WebKit2/Configurations/WebKit2.xcconfig</a></li>
<li><a href="#trunkSourceWebKit2SharedWebOpenPanelParametersh">trunk/Source/WebKit2/Shared/WebOpenPanelParameters.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebOpenPanelResultListenerProxycpp">trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebOpenPanelResultListenerProxyh">trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSh">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSmm">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionh">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebOpenPanelResultListenercpp">trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebOpenPanelResultListenerh">trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFileUploadPanelh">trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFileUploadPanelmm">trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebCore/ChangeLog        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-05-02  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        [iOS] WebKit2 File Upload Support
+        https://bugs.webkit.org/show_bug.cgi?id=132024
+
+        Reviewed by Enrica Casucci.
+
+        * English.lproj/Localizable.strings:
+        New localized strings for &lt;input type=&quot;file&quot;&gt; on iOS.
+
</ins><span class="cx"> 2014-05-02  Chris Fleizach  &lt;cfleizach@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: WK2: iOS web page scrolling doesn't work with VoiceOver
</span></span></pre></div>
<a id="trunkSourceWebCoreEnglishlprojLocalizablestrings"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/English.lproj/Localizable.strings (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/English.lproj/Localizable.strings        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebCore/English.lproj/Localizable.strings        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+/* File Upload multiple photos label */
+&quot;# Photos (file upload on page label for multiple photos)&quot; = &quot;%@ Photos&quot;;
+
+/* File Upload images and videos label */
+&quot;# Photos and # Videos (file upload on page label for image and videos)&quot; = &quot;%@ and %@&quot;;
+
+/* File Upload multiple videos label */
+&quot;# Videos (file upload on page label for multiple videos)&quot; = &quot;%@ Videos&quot;;
+
</ins><span class="cx"> /* accessibility help text for media controller time value &gt;= 1 day */
</span><span class="cx"> &quot;%1$d days %2$d hours %3$d minutes %4$d seconds&quot; = &quot;%1$d days %2$d hours %3$d minutes %4$d seconds&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -55,6 +64,12 @@
</span><span class="cx"> /* Present the element &lt;select multiple&gt; when a single &lt;option&gt; is selected (iOS only) */
</span><span class="cx"> &quot;1 Item&quot; = &quot;1 Item&quot;;
</span><span class="cx"> 
</span><ins>+/* File Upload single photo label */
+&quot;1 Photo (file upload on page label for one photo)&quot; = &quot;1 Photo&quot;;
+
+/* File Upload single video label */
+&quot;1 Video (file upload on page label for one video)&quot; = &quot;1 Video&quot;;
+
</ins><span class="cx"> /* Menu item title for KEYGEN pop-up menu */
</span><span class="cx"> &quot;1024 (Medium Grade)&quot; = &quot;1024 (Medium Grade)&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -94,6 +109,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>+/* File Upload alert sheet button string to cancel */
+&quot;Cancel (file upload action sheet)&quot; = &quot;Cancel&quot;;
+
</ins><span class="cx"> /* Title for Cancel button label in button bar */
</span><span class="cx"> &quot;Cancel button label in button bar&quot; = &quot;Cancel&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -379,6 +397,9 @@
</span><span class="cx"> /* Media Pause context menu item */
</span><span class="cx"> &quot;Pause&quot; = &quot;Pause&quot;;
</span><span class="cx"> 
</span><ins>+/* File Upload alert sheet button string for choosing an existing media item from the Photo Library */
+&quot;Photo Library (file upload action sheet)&quot; = &quot;Photo Library&quot;;
+
</ins><span class="cx"> /* Media Play context menu item */
</span><span class="cx"> &quot;Play&quot; = &quot;Play&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -526,6 +547,15 @@
</span><span class="cx"> /* Undo action name */
</span><span class="cx"> &quot;Superscript (Undo action name)&quot; = &quot;Superscript&quot;;
</span><span class="cx"> 
</span><ins>+/* File Upload alert sheet camera button string for taking only photos */
+&quot;Take Photo (file upload action sheet)&quot; = &quot;Take Photo&quot;;
+
+/* File Upload alert sheet camera button string for taking photos or videos */
+&quot;Take Photo or Video (file upload action sheet)&quot; = &quot;Take Photo or Video&quot;;
+
+/* File Upload alert sheet camera button string for taking only videos */
+&quot;Take Video (file upload action sheet)&quot; = &quot;Take Video&quot;;
+
</ins><span class="cx"> /* Text Replacement context menu item */
</span><span class="cx"> &quot;Text Replacement&quot; = &quot;Text Replacement&quot;;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/ChangeLog        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -1,3 +1,114 @@
</span><ins>+2014-05-02  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        [iOS] WebKit2 File Upload Support
+        https://bugs.webkit.org/show_bug.cgi?id=132024
+
+        Reviewed by Enrica Casucci.
+
+        * Configurations/WebKit2.xcconfig:
+        Include MobileCoreServices on iOS for kUTTypeImage/kUTTypeMovie.
+
+        * WebKit2.xcodeproj/project.pbxproj:
+        Add new files.
+
+        * UIProcess/WebOpenPanelResultListenerProxy.h:
+        * UIProcess/WebOpenPanelResultListenerProxy.cpp:
+        (WebKit::filePathsFromFileURLs):
+        (WebKit::WebOpenPanelResultListenerProxy::chooseFiles):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::runOpenPanel):
+        (WebKit::WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon):
+        * WebProcess/WebPage/WebOpenPanelResultListener.h:
+        * WebProcess/WebPage/WebOpenPanelResultListener.cpp:
+        (WebKit::WebOpenPanelResultListener::didChooseFilesWithDisplayStringAndIcon):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon):
+        Message forwarding for choosing files and providing a display string and icon,
+        leading down to the existing WebCore FileChooser method.
+
+        * UIProcess/PageClient.h:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::handleRunOpenPanel):
+        Add a default handler for file open panel on iOS.
+        Forwards to the content view.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView lastInteractionLocation]):
+        (-[WKContentView _webTouchEventsRecognized:]):
+        (-[WKContentView _highlightLongPressRecognized:]):
+        (-[WKContentView _longPressRecognized:]):
+        (-[WKContentView _singleTapRecognized:]):
+        (-[WKContentView _doubleTapRecognized:]):
+        (-[WKContentView _twoFingerDoubleTapRecognized:]):
+        Keep track of the last interaction location. This matches previous behavior
+        of showing the file upload popover where the user tapped, to handle
+        cases where the &lt;input&gt; is hidden.
+
+        (-[WKContentView _showRunOpenPanel:resultListener:]):
+        (-[WKContentView fileUploadPanelDidDismiss:]):
+        Handle showing the cleaning up after the file upload panel.
+
+        * UIProcess/ios/forms/WKFileUploadPanel.h:
+        * UIProcess/ios/forms/WKFileUploadPanel.mm: Added.
+        (squareCropRectForSize):
+        (squareImage):
+        (thumbnailSizedImageForImage):
+        (-[_WKFileUploadItem isVideo]):
+        (-[_WKFileUploadItem fileURL]):
+        (-[_WKFileUploadItem displayImage]):
+        (-[_WKImageFileUploadItem initWithFilePath:originalImage:]):
+        (-[_WKImageFileUploadItem isVideo]):
+        (-[_WKImageFileUploadItem fileURL]):
+        (-[_WKImageFileUploadItem displayImage]):
+        (-[_WKVideoFileUploadItem initWithFilePath:mediaURL:]):
+        (-[_WKVideoFileUploadItem isVideo]):
+        (-[_WKVideoFileUploadItem fileURL]):
+        (-[_WKVideoFileUploadItem displayImage]):
+        Helper class for each image picker selection. Knows how to get
+        a file URL and thumbnail display image for the item.
+
+        (-[WKFileUploadPanel initWithView:]):
+        (-[WKFileUploadPanel dealloc]):
+        (-[WKFileUploadPanel _dispatchDidDismiss]):
+        (-[WKFileUploadPanel _cancel]):
+        (-[WKFileUploadPanel _chooseFiles:displayString:iconImage:]):
+        Lifetime of the upload panel requires that either cancel or choose
+        must happen as we go through the file picking process.
+
+        (-[WKFileUploadPanel presentWithParameters:WebKit::resultListener:WebKit::]):
+        (-[WKFileUploadPanel dismiss]):
+        API to show or dismiss the panel.
+
+        (-[WKFileUploadPanel _dismissDisplayAnimated:]):
+        Helper to clean up the UI as it progresses or completes no matter the device idiom.
+
+        (-[WKFileUploadPanel _presentPopoverWithContentViewController:animated:]):
+        (-[WKFileUploadPanel _presentFullscreenViewController:animated:]):
+        UI presentation for the appropriate idiom.
+
+        (-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
+        (-[WKFileUploadPanel _showMediaSourceSelectionSheet]):
+        (-[WKFileUploadPanel _showPhotoPickerWithSourceType:]):
+        Showing the action sheet or image picker.
+
+        (-[WKFileUploadPanel popoverControllerDidDismissPopover:]):
+        (-[WKFileUploadPanel _willMultipleSelectionDelegateBeCalled]):
+        (-[WKFileUploadPanel imagePickerController:didFinishPickingMediaWithInfo:]):
+        (-[WKFileUploadPanel imagePickerController:didFinishPickingMultipleMediaWithInfo:]):
+        (-[WKFileUploadPanel imagePickerControllerDidCancel:]):
+        Action sheet or image picker handlers.
+
+        (-[WKFileUploadPanel _processMediaInfoDictionaries:successBlock:failureBlock:]):
+        (-[WKFileUploadPanel _processMediaInfoDictionaries:atIndex:processedResults:processedImageCount:processedVideoCount:successBlock:failureBlock:]):
+        (-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):
+        (-[WKFileUploadPanel _displayStringForPhotos:videos:]):
+        Processing selections from the image picker to FileUploadItems.
+
</ins><span class="cx"> 2014-05-01  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS WK2] Animations on vox.com look wrong
</span></span></pre></div>
<a id="trunkSourceWebKit2ConfigurationsWebKit2xcconfig"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Configurations/WebKit2.xcconfig (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Configurations/WebKit2.xcconfig        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/Configurations/WebKit2.xcconfig        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -19,7 +19,7 @@
</span><span class="cx"> // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
</span><span class="cx"> // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span class="cx"> // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><del>-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</del><ins>+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;BaseTarget.xcconfig&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> DYLIB_INSTALL_NAME_BASE = $(NORMAL_WEBKIT2_FRAMEWORKS_DIR);
</span><span class="cx"> 
</span><span class="cx"> FRAMEWORK_AND_LIBRARY_LDFLAGS = $(FRAMEWORK_AND_LIBRARY_LDFLAGS_$(PLATFORM_NAME));
</span><del>-FRAMEWORK_AND_LIBRARY_LDFLAGS_iphonesimulator = -lobjc -framework AssertionServices -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CorePDF -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework UIKit -framework OpenGLES -framework MobileAsset -framework WebKit -lMobileGestalt -lassertion_extension;
</del><ins>+FRAMEWORK_AND_LIBRARY_LDFLAGS_iphonesimulator = -lobjc -framework AssertionServices -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CorePDF -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework UIKit -framework OpenGLES -framework MobileAsset -framework MobileCoreServices -framework WebKit -lMobileGestalt -lassertion_extension;
</ins><span class="cx"> FRAMEWORK_AND_LIBRARY_LDFLAGS_iphoneos = $(FRAMEWORK_AND_LIBRARY_LDFLAGS_iphonesimulator) -framework IOSurface;
</span><span class="cx"> FRAMEWORK_AND_LIBRARY_LDFLAGS_macosx = -framework ApplicationServices -framework Carbon -framework Cocoa -framework CoreServices -framework IOKit -framework CoreAudio -framework IOSurface -framework OpenGL;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebOpenPanelParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebOpenPanelParameters.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebOpenPanelParameters.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/Shared/WebOpenPanelParameters.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     static PassRefPtr&lt;WebOpenPanelParameters&gt; create(const WebCore::FileChooserSettings&amp;);
</span><span class="cx">     ~WebOpenPanelParameters();
</span><span class="cx"> 
</span><del>-    bool allowMultipleFiles() const { return m_settings.allowsMultipleFiles; } 
</del><ins>+    bool allowMultipleFiles() const { return m_settings.allowsMultipleFiles; }
</ins><span class="cx">     PassRefPtr&lt;API::Array&gt; acceptMIMETypes() const;
</span><span class="cx">     PassRefPtr&lt;API::Array&gt; selectedFileNames() const;
</span><span class="cx"> #if ENABLE(MEDIA_CAPTURE)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -150,6 +150,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void handleDownloadRequest(DownloadProxy*) = 0;
</span><span class="cx"> 
</span><ins>+    virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters*, WebOpenPanelResultListenerProxy*) { return false; }
+
</ins><span class="cx"> #if PLATFORM(EFL)
</span><span class="cx">     virtual void didChangeContentSize(const WebCore::IntSize&amp;) = 0;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebOpenPanelResultListenerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include &quot;WebOpenPanelResultListenerProxy.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;APIArray.h&quot;
</span><ins>+#include &quot;APIString.h&quot;
</ins><span class="cx"> #include &quot;WebPageProxy.h&quot;
</span><span class="cx"> #include &lt;WebCore/URL.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -44,27 +45,40 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebOpenPanelResultListenerProxy::chooseFiles(API::Array* fileURLsArray)
</del><ins>+static Vector&lt;String&gt; filePathsFromFileURLs(const API::Array&amp; fileURLs)
</ins><span class="cx"> {
</span><del>-    if (!m_page)
-        return;
</del><ins>+    Vector&lt;String&gt; filePaths;
</ins><span class="cx"> 
</span><del>-    size_t size = fileURLsArray-&gt;size();
-
-    Vector&lt;String&gt; filePaths;
</del><ins>+    size_t size = fileURLs.size();
</ins><span class="cx">     filePaths.reserveInitialCapacity(size);
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; size; ++i) {
</span><del>-        API::URL* apiURL = fileURLsArray-&gt;at&lt;API::URL&gt;(i);
-        if (apiURL) {
-            URL url(URL(), apiURL-&gt;string());
-            filePaths.uncheckedAppend(url.fileSystemPath());
-        }
</del><ins>+        API::URL* apiURL = fileURLs.at&lt;API::URL&gt;(i);
+        if (apiURL)
+            filePaths.uncheckedAppend(URL(URL(), apiURL-&gt;string()).fileSystemPath());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_page-&gt;didChooseFilesForOpenPanel(filePaths);
</del><ins>+    return filePaths;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+void WebOpenPanelResultListenerProxy::chooseFiles(API::Array* fileURLsArray, API::String* displayString, const API::Data* iconImageData)
+{
+    if (!m_page)
+        return;
+
+    m_page-&gt;didChooseFilesForOpenPanelWithDisplayStringAndIcon(filePathsFromFileURLs(*fileURLsArray), displayString ? displayString-&gt;string() : String(), iconImageData);
+}
+#endif
+
+void WebOpenPanelResultListenerProxy::chooseFiles(API::Array* fileURLsArray)
+{
+    if (!m_page)
+        return;
+
+    m_page-&gt;didChooseFilesForOpenPanel(filePathsFromFileURLs(*fileURLsArray));
+}
+
</ins><span class="cx"> void WebOpenPanelResultListenerProxy::cancel()
</span><span class="cx"> {
</span><span class="cx">     if (!m_page)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebOpenPanelResultListenerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace API {
</span><span class="cx"> class Array;
</span><ins>+class Data;
+class String;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="lines">@@ -47,6 +49,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~WebOpenPanelResultListenerProxy();
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    void chooseFiles(API::Array*, API::String* displayString, const API::Data* iconImageData);
+#endif
</ins><span class="cx">     void chooseFiles(API::Array*);
</span><span class="cx">     void cancel();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -3083,8 +3083,10 @@
</span><span class="cx">     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
</span><span class="cx">     m_process-&gt;responsivenessTimer()-&gt;stop();
</span><span class="cx"> 
</span><del>-    if (!m_uiClient-&gt;runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
-        didCancelForOpenPanel();
</del><ins>+    if (!m_uiClient-&gt;runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
+        if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
+            didCancelForOpenPanel();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::printFrame(uint64_t frameID)
</span><span class="lines">@@ -3592,6 +3594,19 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(CONTEXT_MENUS)
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+void WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp; fileURLs, const String&amp; displayString, const API::Data* iconData)
+{
+    if (!isValid())
+        return;
+
+    m_process-&gt;send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData-&gt;dataReference() : IPC::DataReference()), m_pageID);
+
+    m_openPanelResultListener-&gt;invalidate();
+    m_openPanelResultListener = nullptr;
+}
+#endif
+
</ins><span class="cx"> void WebPageProxy::didChooseFilesForOpenPanel(const Vector&lt;String&gt;&amp; fileURLs)
</span><span class="cx"> {
</span><span class="cx">     if (!isValid())
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -946,6 +946,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Called by the WebOpenPanelResultListenerProxy.
</span><ins>+#if PLATFORM(IOS)
+    void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp;, const String&amp; displayString, const API::Data* iconData);
+#endif
</ins><span class="cx">     void didChooseFilesForOpenPanel(const Vector&lt;String&gt;&amp;);
</span><span class="cx">     void didCancelForOpenPanel();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -120,6 +120,8 @@
</span><span class="cx">     virtual void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) override;
</span><span class="cx">     virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect&amp; elementRect) override;
</span><span class="cx"> 
</span><ins>+    virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters*, WebOpenPanelResultListenerProxy*) override;
+
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx">     virtual void showInspectorIndication() override;
</span><span class="cx">     virtual void hideInspectorIndication() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -414,6 +414,12 @@
</span><span class="cx">     [m_contentView _showPlaybackTargetPicker:hasVideo fromRect:elementRect];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool PageClientImpl::handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener)
+{
+    [m_contentView _showRunOpenPanel:parameters resultListener:listener];
+    return true;
+}
+
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> void PageClientImpl::showInspectorIndication()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #import &quot;GestureTypes.h&quot;
</span><span class="cx"> #import &quot;InteractionInformationAtPosition.h&quot;
</span><span class="cx"> #import &quot;WKAirPlayRoutePicker.h&quot;
</span><ins>+#import &quot;WKFileUploadPanel.h&quot;
</ins><span class="cx"> #import &quot;WKFormPeripheral.h&quot;
</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">@@ -51,14 +52,16 @@
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> class NativeWebTouchEvent;
</span><span class="cx"> class SmartMagnificationController;
</span><ins>+class WebOpenPanelParameters;
+class WebOpenPanelResultListenerProxy;
</ins><span class="cx"> class WebPageProxy;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-@class _UIWebHighlightLongPressGestureRecognizer;
-@class _UIHighlightView;
-@class WebIOSEvent;
</del><span class="cx"> @class WKActionSheetAssistant;
</span><span class="cx"> @class WKFormInputSession;
</span><ins>+@class WebIOSEvent;
+@class _UIHighlightView;
+@class _UIWebHighlightLongPressGestureRecognizer;
</ins><span class="cx"> 
</span><span class="cx"> typedef void (^UIWKAutocorrectionCompletionHandler)(UIWKAutocorrectionRects *rectsForInput);
</span><span class="cx"> typedef void (^UIWKAutocorrectionContextHandler)(UIWKAutocorrectionContext *autocorrectionContext);
</span><span class="lines">@@ -98,6 +101,7 @@
</span><span class="cx">     RetainPtr&lt;WKActionSheetAssistant&gt; _actionSheetAssistant;
</span><span class="cx">     RetainPtr&lt;WKAirPlayRoutePicker&gt; _airPlayRoutePicker;
</span><span class="cx">     RetainPtr&lt;WKFormInputSession&gt; _formInputSession;
</span><ins>+    RetainPtr&lt;WKFileUploadPanel&gt; _fileUploadPanel;
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;WebKit::SmartMagnificationController&gt; _smartMagnificationController;
</span><span class="cx"> 
</span><span class="lines">@@ -110,6 +114,8 @@
</span><span class="cx">     WebKit::AssistedNodeInformation _assistedNodeInformation;
</span><span class="cx">     RetainPtr&lt;NSObject&lt;WKFormPeripheral&gt;&gt; _inputPeripheral;
</span><span class="cx"> 
</span><ins>+    CGPoint _lastInteractionLocation;
+
</ins><span class="cx">     BOOL _isEditable;
</span><span class="cx">     BOOL _showingTextStyleOptions;
</span><span class="cx">     BOOL _hasValidPositionInformation;
</span><span class="lines">@@ -120,8 +126,9 @@
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span><del>-@interface WKContentView (WKInteraction) &lt;UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol&gt;
</del><ins>+@interface WKContentView (WKInteraction) &lt;UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate&gt;
</ins><span class="cx"> 
</span><ins>+@property (nonatomic, readonly) CGPoint lastInteractionLocation;
</ins><span class="cx"> @property (nonatomic, readonly) BOOL isEditable;
</span><span class="cx"> @property (nonatomic, readonly) const WebKit::InteractionInformationAtPosition&amp; positionInformation;
</span><span class="cx"> @property (nonatomic, readonly) const WebKit::WKAutoCorrectionData&amp; autocorrectionData;
</span><span class="lines">@@ -148,6 +155,7 @@
</span><span class="cx"> - (void)_didEndScrollingOrZooming;
</span><span class="cx"> - (void)_didUpdateBlockSelectionWithTouch:(WebKit::SelectionTouch)touch withFlags:(WebKit::SelectionFlags)flags growThreshold:(CGFloat)growThreshold shrinkThreshold:(CGFloat)shrinkThreshold;
</span><span class="cx"> - (void)_showPlaybackTargetPicker:(BOOL)hasVideo fromRect:(const WebCore::IntRect&amp;)elementRect;
</span><ins>+- (void)_showRunOpenPanel:(WebKit::WebOpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
</ins><span class="cx"> - (void)accessoryDone;
</span><span class="cx"> - (Vector&lt;WebKit::WKOptionItem&gt;&amp;) assistedNodeSelectOptions;
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -32,20 +32,18 @@
</span><span class="cx"> #import &quot;NativeWebKeyboardEvent.h&quot;
</span><span class="cx"> #import &quot;NativeWebTouchEvent.h&quot;
</span><span class="cx"> #import &quot;SmartMagnificationController.h&quot;
</span><ins>+#import &quot;WKActionSheetAssistant.h&quot;
+#import &quot;WKFormInputControl.h&quot;
+#import &quot;WKFormSelectControl.h&quot;
+#import &quot;WKWebViewPrivate.h&quot;
</ins><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><del>-#import &quot;WKActionSheetAssistant.h&quot;
-#import &quot;WKFormInputControl.h&quot;
-#import &quot;WKFormSelectControl.h&quot;
-#import &quot;WKWebViewPrivate.h&quot;
</del><span class="cx"> #import &quot;_WKFormDelegate.h&quot;
</span><span class="cx"> #import &quot;_WKFormInputSession.h&quot;
</span><span class="cx"> #import &lt;DataDetectorsUI/DDDetectionController.h&gt;
</span><span class="cx"> #import &lt;TextInput/TI_NSStringExtras.h&gt;
</span><del>-#import &lt;UIKit/_UIHighlightView.h&gt;
-#import &lt;UIKit/_UIWebHighlightLongPressGestureRecognizer.h&gt;
</del><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">@@ -54,6 +52,8 @@
</span><span class="cx"> #import &lt;UIKit/UITapGestureRecognizer_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UITextInteractionAssistant_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIWebDocumentView.h&gt; // FIXME: should not include this header.
</span><ins>+#import &lt;UIKit/_UIHighlightView.h&gt;
+#import &lt;UIKit/_UIWebHighlightLongPressGestureRecognizer.h&gt;
</ins><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><span class="lines">@@ -240,6 +240,11 @@
</span><span class="cx">     [_doubleTapGestureRecognizer setDelegate:nil];
</span><span class="cx">     [_highlightLongPressGestureRecognizer setDelegate:nil];
</span><span class="cx">     [_longPressGestureRecognizer setDelegate:nil];
</span><ins>+
+    if (_fileUploadPanel) {
+        [_fileUploadPanel setDelegate:nil];
+        [_fileUploadPanel dismiss];
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (const InteractionInformationAtPosition&amp;)positionInformation
</span><span class="lines">@@ -257,6 +262,11 @@
</span><span class="cx">     return _inputDelegate;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (CGPoint)lastInteractionLocation
+{
+    return _lastInteractionLocation;
+}
+
</ins><span class="cx"> - (BOOL)isEditable
</span><span class="cx"> {
</span><span class="cx">     return _isEditable;
</span><span class="lines">@@ -288,6 +298,8 @@
</span><span class="cx">     if (nativeWebTouchEvent.type() == WebKit::WebEvent::TouchStart)
</span><span class="cx">         _canSendTouchEventsAsynchronously = NO;
</span><span class="cx"> 
</span><ins>+    _lastInteractionLocation = gestureRecognizer.locationInWindow;
+
</ins><span class="cx">     if (_canSendTouchEventsAsynchronously)
</span><span class="cx">         _page-&gt;handleTouchEventAsynchronously(nativeWebTouchEvent);
</span><span class="cx">     else
</span><span class="lines">@@ -669,6 +681,8 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(gestureRecognizer == _highlightLongPressGestureRecognizer);
</span><span class="cx"> 
</span><ins>+    _lastInteractionLocation = gestureRecognizer.startPoint;
+
</ins><span class="cx">     switch ([gestureRecognizer state]) {
</span><span class="cx">     case UIGestureRecognizerStateBegan:
</span><span class="cx">         _page-&gt;tapHighlightAtPosition([gestureRecognizer startPoint], _latestTapHighlightID);
</span><span class="lines">@@ -690,6 +704,8 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(gestureRecognizer == _longPressGestureRecognizer);
</span><span class="cx"> 
</span><ins>+    _lastInteractionLocation = gestureRecognizer.startPoint;
+
</ins><span class="cx">     if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
</span><span class="cx">         SEL action = [self _actionForLongPress];
</span><span class="cx">         if (action)
</span><span class="lines">@@ -706,16 +722,22 @@
</span><span class="cx"> 
</span><span class="cx">     [_webSelectionAssistant clearSelection];
</span><span class="cx"> 
</span><del>-    [self _attemptClickAtLocation:[gestureRecognizer location]];
</del><ins>+    _lastInteractionLocation = gestureRecognizer.location;
+
+    [self _attemptClickAtLocation:gestureRecognizer.location];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_doubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
</span><span class="cx"> {
</span><ins>+    _lastInteractionLocation = gestureRecognizer.location;
+
</ins><span class="cx">     _smartMagnificationController-&gt;handleSmartMagnificationGesture(gestureRecognizer.location);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_twoFingerDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
</span><span class="cx"> {
</span><ins>+    _lastInteractionLocation = gestureRecognizer.location;
+
</ins><span class="cx">     _smartMagnificationController-&gt;handleResetMagnificationGesture(gestureRecognizer.location);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2088,6 +2110,26 @@
</span><span class="cx">     [_airPlayRoutePicker show:hasVideo fromRect:elementRect];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_showRunOpenPanel:(WebOpenPanelParameters*)parameters resultListener:(WebOpenPanelResultListenerProxy*)listener
+{
+    ASSERT(!_fileUploadPanel);
+    if (_fileUploadPanel)
+        return;
+
+    _fileUploadPanel = adoptNS([[WKFileUploadPanel alloc] initWithView:self]);
+    [_fileUploadPanel setDelegate:self];
+    [_fileUploadPanel presentWithParameters:parameters resultListener:listener];
+}
+
+- (void)fileUploadPanelDidDismiss:(WKFileUploadPanel *)fileUploadPanel
+{
+    ASSERT(_fileUploadPanel.get() == fileUploadPanel);
+
+    [_fileUploadPanel setDelegate:nil];
+    [_fileUploadPanel release];
+    _fileUploadPanel = nil;
+}
+
</ins><span class="cx"> #pragma mark - Implementation of UIWebTouchEventsGestureRecognizerDelegate.
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)shouldIgnoreWebTouch
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFileUploadPanelhfromrev168179trunkSourceWebKit2WebProcessWebPageWebOpenPanelResultListenercpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.h (from rev 168179, trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp) (0 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.h        2014-05-02 19:28:30 UTC (rev 168180)
</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.
+ */
+
+#if PLATFORM(IOS)
+
+#import &lt;UIKit/UIViewController.h&gt;
+
+@class WKContentView;
+@protocol WKFileUploadPanelDelegate;
+
+namespace WebKit {
+class WebOpenPanelParameters;
+class WebOpenPanelResultListenerProxy;
+}
+
+@interface WKFileUploadPanel : UIViewController
+@property (nonatomic, assign) id &lt;WKFileUploadPanelDelegate&gt; delegate;
+- (instancetype)initWithView:(WKContentView *)view;
+- (void)presentWithParameters:(WebKit::WebOpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
+- (void)dismiss;
+@end
+
+@protocol WKFileUploadPanelDelegate &lt;NSObject&gt;
+@optional
+- (void)fileUploadPanelDidDismiss:(WKFileUploadPanel *)fileUploadPanel;
+@end
+
+#endif // PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFileUploadPanelmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm (0 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -0,0 +1,709 @@
</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;WKFileUploadPanel.h&quot;
+
+#if PLATFORM(IOS)
+
+#import &quot;APIArray.h&quot;
+#import &quot;APIData.h&quot;
+#import &quot;APIString.h&quot;
+#import &quot;WKContentViewInteraction.h&quot;
+#import &quot;WKData.h&quot;
+#import &quot;WKStringCF.h&quot;
+#import &quot;WKURLCF.h&quot;
+#import &quot;WebOpenPanelParameters.h&quot;
+#import &quot;WebOpenPanelResultListenerProxy.h&quot;
+#import &quot;WebPageProxy.h&quot;
+#import &lt;AVFoundation/AVFoundation.h&gt;
+#import &lt;CoreMedia/CoreMedia.h&gt;
+#import &lt;MobileCoreServices/MobileCoreServices.h&gt;
+#import &lt;UIKit/UIAlertController_Private.h&gt;
+#import &lt;UIKit/UIApplication_Private.h&gt;
+#import &lt;UIKit/UIImagePickerController_Private.h&gt;
+#import &lt;UIKit/UIImage_Private.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;WebKit/WebNSFileManagerExtras.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+using namespace WebKit;
+
+SOFT_LINK_FRAMEWORK(AVFoundation);
+SOFT_LINK_CLASS(AVFoundation, AVAssetImageGenerator);
+SOFT_LINK_CLASS(AVFoundation, AVURLAsset);
+#define AVAssetImageGenerator_class getAVAssetImageGeneratorClass()
+#define AVURLAsset_class getAVURLAssetClass()
+
+SOFT_LINK_FRAMEWORK(CoreMedia);
+SOFT_LINK_CONSTANT(CoreMedia, kCMTimeZero, CMTime);
+#define kCMTimeZero getkCMTimeZero()
+
+
+#pragma mark - _WKFileUploadItem
+
+static CGRect squareCropRectForSize(CGSize size)
+{
+    CGFloat smallerSide = MIN(size.width, size.height);
+    CGRect cropRect = CGRectMake(0, 0, smallerSide, smallerSide);
+
+    if (size.width &lt; size.height)
+        cropRect.origin.y = rintf((size.height - smallerSide) / 2);
+    else
+        cropRect.origin.x = rintf((size.width - smallerSide) / 2);
+
+    return cropRect;
+}
+
+static UIImage *squareImage(UIImage *image)
+{
+    if (!image)
+        return nil;
+
+    CGImageRef imageRef = [image CGImage];
+    CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
+    if (imageSize.width == imageSize.height)
+        return image;
+
+    CGRect squareCropRect = squareCropRectForSize(imageSize);
+    CGImageRef squareImageRef = CGImageCreateWithImageInRect(imageRef, squareCropRect);
+    UIImage *squareImage = [[UIImage alloc] initWithCGImage:squareImageRef imageOrientation:[image imageOrientation]];
+    CGImageRelease(squareImageRef);
+    return [squareImage autorelease];
+}
+
+static UIImage *thumbnailSizedImageForImage(UIImage *image)
+{
+    UIImage *squaredImage = squareImage(image);
+    if (!squaredImage)
+        return nil;
+
+    CGRect destRect = CGRectMake(0, 0, 100, 100);
+    UIGraphicsBeginImageContext(destRect.size);
+    CGContextSetInterpolationQuality(UIGraphicsGetCurrentContext(), kCGInterpolationHigh);
+    [squaredImage drawInRect:destRect];
+    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return resultImage;
+}
+
+
+@interface _WKFileUploadItem : NSObject
+@property (nonatomic, readonly, getter=isVideo) BOOL video;
+@property (nonatomic, readonly) NSURL *fileURL;
+@property (nonatomic, readonly) UIImage *displayImage;
+@end
+
+@implementation _WKFileUploadItem
+
+- (BOOL)isVideo
+{
+    ASSERT_NOT_REACHED();
+    return NO;
+}
+
+- (NSURL *)fileURL
+{
+    ASSERT_NOT_REACHED();
+    return nil;
+}
+
+- (UIImage *)displayImage
+{
+    ASSERT_NOT_REACHED();
+    return nil;
+}
+
+@end
+
+
+@interface _WKImageFileUploadItem : _WKFileUploadItem
+- (instancetype)initWithFilePath:(NSString *)filePath originalImage:(UIImage *)originalImage;
+@end
+
+@implementation _WKImageFileUploadItem {
+    RetainPtr&lt;NSString&gt; _filePath;
+    RetainPtr&lt;UIImage&gt; _originalImage;
+}
+
+- (instancetype)initWithFilePath:(NSString *)filePath originalImage:(UIImage *)originalImage
+{
+    if (!(self = [super init]))
+        return nil;
+    _filePath = filePath;
+    _originalImage = originalImage;
+    return self;
+}
+
+- (BOOL)isVideo
+{
+    return NO;
+}
+
+- (NSURL *)fileURL
+{
+    return [NSURL fileURLWithPath:_filePath.get()];
+}
+
+- (UIImage *)displayImage
+{
+    return thumbnailSizedImageForImage(_originalImage.get());
+}
+
+@end
+
+
+@interface _WKVideoFileUploadItem : _WKFileUploadItem
+- (instancetype)initWithFilePath:(NSString *)filePath mediaURL:(NSURL *)mediaURL;
+@end
+
+@implementation _WKVideoFileUploadItem {
+    RetainPtr&lt;NSString&gt; _filePath;
+    RetainPtr&lt;NSURL&gt; _mediaURL;
+}
+
+- (instancetype)initWithFilePath:(NSString *)filePath mediaURL:(NSURL *)mediaURL
+{
+    if (!(self = [super init]))
+        return nil;
+    _filePath = filePath;
+    _mediaURL = mediaURL;
+    return self;
+}
+
+- (BOOL)isVideo
+{
+    return YES;
+}
+
+- (NSURL *)fileURL
+{
+    return [NSURL fileURLWithPath:_filePath.get()];
+}
+
+- (UIImage *)displayImage
+{
+    RetainPtr&lt;AVURLAsset&gt; asset = adoptNS([[AVURLAsset_class alloc] initWithURL:_mediaURL.get() options:nil]);
+    RetainPtr&lt;AVAssetImageGenerator&gt; generator = adoptNS([[AVAssetImageGenerator_class alloc] initWithAsset:asset.get()]);
+    [generator setAppliesPreferredTrackTransform:YES];
+
+    NSError *error = nil;
+    RetainPtr&lt;CGImageRef&gt; imageRef = adoptCF([generator copyCGImageAtTime:kCMTimeZero actualTime:nil error:&amp;error]);
+    if (error) {
+        LOG_ERROR(&quot;_WKVideoFileUploadItem: Error creating image for video: %@&quot;, _mediaURL.get());
+        return nil;
+    }
+
+    RetainPtr&lt;UIImage&gt; image = adoptNS([[UIImage alloc] initWithCGImage:imageRef.get()]);
+    return thumbnailSizedImageForImage(image.get());
+}
+
+@end
+
+
+#pragma mark - WKFileUploadPanel
+
+@interface WKFileUploadPanel () &lt;UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate&gt;
+@end
+
+@implementation WKFileUploadPanel {
+    WKContentView *_view;
+    WebKit::WebOpenPanelResultListenerProxy* _listener;
+    RetainPtr&lt;NSArray&gt; _mimeTypes;
+    CGPoint _interactionPoint;
+    BOOL _allowMultipleFiles;
+    BOOL _usingCamera;
+    RetainPtr&lt;UIImagePickerController&gt; _imagePicker;
+    RetainPtr&lt;UIAlertController&gt; _actionSheetController;
+    RetainPtr&lt;UIViewController&gt; _presentationViewController; // iPhone always. iPad for Fullscreen Camera.
+    RetainPtr&lt;UIPopoverController&gt; _presentationPopover; // iPad for action sheet and Photo Library.
+}
+
+- (instancetype)initWithView:(WKContentView *)view
+{
+    if (!(self = [super init]))
+        return nil;
+    _view = view;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_imagePicker setDelegate:nil];
+    [_presentationPopover setDelegate:nil];
+    [super dealloc];
+}
+
+- (void)_dispatchDidDismiss
+{
+    if ([_delegate respondsToSelector:@selector(fileUploadPanelDidDismiss:)])
+        [_delegate fileUploadPanelDidDismiss:self];
+}
+
+#pragma mark - Panel Completion (one of these must be called)
+
+- (void)_cancel
+{
+    _listener-&gt;cancel();
+    [self _dispatchDidDismiss];
+}
+
+- (void)_chooseFiles:(NSArray *)fileURLs displayString:(NSString *)displayString iconImage:(UIImage *)iconImage
+{
+    NSUInteger count = [fileURLs count];
+    if (!count) {
+        [self _cancel];
+        return;
+    }
+
+    Vector&lt;RefPtr&lt;API::Object&gt;&gt; urls;
+    urls.reserveInitialCapacity(count);
+    for (NSURL *fileURL in fileURLs)
+        urls.uncheckedAppend(adoptRef(toImpl(WKURLCreateWithCFURL((CFURLRef)fileURL))));
+    RefPtr&lt;API::Array&gt; fileURLsRef = API::Array::create(std::move(urls));
+
+    NSData *jpeg = UIImageJPEGRepresentation(iconImage, 1.0);
+    RefPtr&lt;API::Data&gt; iconImageDataRef = adoptRef(toImpl(WKDataCreate(reinterpret_cast&lt;const unsigned char*&gt;([jpeg bytes]), [jpeg length])));
+
+    RefPtr&lt;API::String&gt; displayStringRef = adoptRef(toImpl(WKStringCreateWithCFString((CFStringRef)displayString)));
+
+    _listener-&gt;chooseFiles(fileURLsRef.get(), displayStringRef.get(), iconImageDataRef.get());
+    [self _dispatchDidDismiss];
+}
+
+#pragma mark - Present / Dismiss API
+
+- (void)presentWithParameters:(WebKit::WebOpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener
+{
+    ASSERT(!_listener);
+
+    _listener = listener;
+    _allowMultipleFiles = parameters-&gt;allowMultipleFiles();
+    _interactionPoint = [_view lastInteractionLocation];
+
+    RefPtr&lt;API::Array&gt; acceptMimeTypes = parameters-&gt;acceptMIMETypes();
+    NSMutableArray *mimeTypes = [NSMutableArray arrayWithCapacity:acceptMimeTypes-&gt;size()];
+    for (const auto&amp; mimeType : acceptMimeTypes-&gt;elementsOfType&lt;API::String&gt;())
+        [mimeTypes addObject:mimeType-&gt;string()];
+    _mimeTypes = adoptNS([mimeTypes copy]);
+
+    // If there is no camera or this is type=multiple, just show the image picker for the photo library.
+    // Otherwise, show an action sheet for the user to choose between camera or library.
+    if (_allowMultipleFiles || ![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
+        [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
+    else
+        [self _showMediaSourceSelectionSheet];
+}
+
+- (void)dismiss
+{
+    [self _dismissDisplayAnimated:NO];
+    [self _cancel];
+}
+
+- (void)_dismissDisplayAnimated:(BOOL)animated
+{
+    if (_presentationPopover) {
+        [_presentationPopover dismissPopoverAnimated:animated];
+        [_presentationPopover setDelegate:nil];
+        _presentationPopover = nil;
+    }
+
+    if (_presentationViewController) {
+        [_presentationViewController dismissViewControllerAnimated:animated completion:^{
+            _presentationViewController = nil;
+        }];
+    }
+}
+
+#pragma mark - Action Sheet
+
+static bool stringHasPrefixCaseInsensitive(NSString *str, NSString *prefix)
+{
+    NSRange range = [str rangeOfString:prefix options:(NSCaseInsensitiveSearch | NSAnchoredSearch)];
+    return range.location != NSNotFound;
+}
+
+- (NSArray *)_mediaTypesForPickerSourceType:(UIImagePickerControllerSourceType)sourceType
+{
+    // The HTML5 spec mentions the literal &quot;image/*&quot; and &quot;video/*&quot; strings.
+    // We support these and go a step further, if the MIME type starts with
+    // &quot;image/&quot; or &quot;video/&quot; we adjust the picker's image or video filters.
+    // So, &quot;image/jpeg&quot; would make the picker display all images types.
+    NSMutableSet *mediaTypes = [NSMutableSet set];
+    for (NSString *mimeType in _mimeTypes.get()) {
+        if (stringHasPrefixCaseInsensitive(mimeType, @&quot;image/&quot;))
+            [mediaTypes addObject:(NSString *)kUTTypeImage];
+        else if (stringHasPrefixCaseInsensitive(mimeType, @&quot;video/&quot;))
+            [mediaTypes addObject:(NSString *)kUTTypeMovie];
+    }
+
+    if ([mediaTypes count])
+        return [mediaTypes allObjects];
+
+    // Fallback to every supported media type if there is no filter.
+    return [UIImagePickerController availableMediaTypesForSourceType:sourceType];
+}
+
+- (void)_showMediaSourceSelectionSheet
+{
+    NSString *existingString = WEB_UI_STRING_KEY(&quot;Photo Library&quot;, &quot;Photo Library (file upload action sheet)&quot;, &quot;File Upload alert sheet button string for choosing an existing media item from the Photo Library&quot;);
+    NSString *cancelString = WEB_UI_STRING_KEY(&quot;Cancel&quot;, &quot;Cancel (file upload action sheet)&quot;, &quot;File Upload alert sheet button string to cancel&quot;);
+
+    // Choose the appropriate string for the camera button.
+    NSString *cameraString;
+    NSArray *filteredMediaTypes = [self _mediaTypesForPickerSourceType:UIImagePickerControllerSourceTypeCamera];
+    BOOL containsImageMediaType = [filteredMediaTypes containsObject:(NSString *)kUTTypeImage];
+    BOOL containsVideoMediaType = [filteredMediaTypes containsObject:(NSString *)kUTTypeMovie];
+    ASSERT(containsImageMediaType || containsVideoMediaType);
+    if (containsImageMediaType &amp;&amp; containsVideoMediaType)
+        cameraString = WEB_UI_STRING_KEY(&quot;Take Photo or Video&quot;, &quot;Take Photo or Video (file upload action sheet)&quot;, &quot;File Upload alert sheet camera button string for taking photos or videos&quot;);
+    else if (containsVideoMediaType)
+        cameraString = WEB_UI_STRING_KEY(&quot;Take Video&quot;, &quot;Take Video (file upload action sheet)&quot;, &quot;File Upload alert sheet camera button string for taking only videos&quot;);
+    else
+        cameraString = WEB_UI_STRING_KEY(&quot;Take Photo&quot;, &quot;Take Photo (file upload action sheet)&quot;, &quot;File Upload alert sheet camera button string for taking only photos&quot;);
+
+    _actionSheetController = [UIAlertController _alertControllerWithTitle:nil message:nil];
+    [_actionSheetController setPreferredStyle:UIAlertControllerStyleActionSheet];
+
+    [_actionSheetController _addActionWithTitle:cancelString style:UIAlertActionStyleCancel handler:^{
+        [self _cancel];
+        // We handled cancel ourselves. Prevent the popover controller delegate from cancelling when the popover dismissed.
+        [_presentationPopover setDelegate:nil];
+    }];
+
+    [_actionSheetController _addActionWithTitle:cameraString style:UIAlertActionStyleDefault handler:^{
+        _usingCamera = YES;
+        [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypeCamera];
+    }];
+
+    [_actionSheetController _addActionWithTitle:existingString style:UIAlertActionStyleDefault handler:^{
+        [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
+    }];
+
+    if (UICurrentUserInterfaceIdiomIsPad())
+        [self _presentPopoverWithContentViewController:_actionSheetController.get() animated:YES];
+    else
+        [self _presentFullscreenViewController:_actionSheetController.get() animated:YES];
+}
+
+#pragma mark - Image Picker
+
+- (void)_showPhotoPickerWithSourceType:(UIImagePickerControllerSourceType)sourceType
+{
+    _imagePicker = adoptNS([[UIImagePickerController alloc] init]);
+    [_imagePicker setDelegate:self];
+    [_imagePicker setSourceType:sourceType];
+    [_imagePicker setAllowsEditing:NO];
+    [_imagePicker setModalPresentationStyle:UIModalPresentationFullScreen];
+    [_imagePicker _setAllowsMultipleSelection:_allowMultipleFiles];
+    [_imagePicker setMediaTypes:[self _mediaTypesForPickerSourceType:sourceType]];
+
+    // Use a popover on the iPad if the source type is not the camera.
+    // The camera will use a fullscreen, modal view controller.
+    BOOL usePopover = UICurrentUserInterfaceIdiomIsPad() &amp;&amp; sourceType != UIImagePickerControllerSourceTypeCamera;
+    if (usePopover)
+        [self _presentPopoverWithContentViewController:_imagePicker.get() animated:YES];
+    else
+        [self _presentFullscreenViewController:_imagePicker.get() animated:YES];
+}
+
+#pragma mark - Presenting View Controllers
+
+- (void)_presentPopoverWithContentViewController:(UIViewController *)contentViewController animated:(BOOL)animated
+{
+    [self _dismissDisplayAnimated:animated];
+
+    _presentationPopover = adoptNS([[UIPopoverController alloc] initWithContentViewController:contentViewController]);
+    [_presentationPopover setDelegate:self];
+    [_presentationPopover presentPopoverFromRect:CGRectIntegral(CGRectMake(_interactionPoint.x, _interactionPoint.y, 1, 1)) inView:_view permittedArrowDirections:UIPopoverArrowDirectionAny animated:animated];
+}
+
+- (void)_presentFullscreenViewController:(UIViewController *)viewController animated:(BOOL)animated
+{
+    [self _dismissDisplayAnimated:animated];
+
+    _presentationViewController = [UIViewController _viewControllerForFullScreenPresentationFromView:_view];
+    [_presentationViewController presentViewController:viewController animated:animated completion:nil];
+}
+
+#pragma mark - UIPopoverControllerDelegate
+
+- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
+{
+    [self _cancel];
+}
+
+#pragma mark - UIImagePickerControllerDelegate implementation
+
+- (BOOL)_willMultipleSelectionDelegateBeCalled
+{
+    // The multiple selection delegate will not be called when the UIImagePicker was not multiple selection.
+    if (!_allowMultipleFiles)
+        return NO;
+
+    // The multiple selection delegate will not be called when we used the camera in the UIImagePicker.
+    if (_usingCamera)
+        return NO;
+
+    return YES;
+}
+
+- (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMediaWithInfo:(NSDictionary *)info
+{
+    // Sometimes both delegates get called, sometimes just one. Always let the
+    // multiple selection delegate handle everything if it will get called.
+    if ([self _willMultipleSelectionDelegateBeCalled])
+        return;
+
+    [self _dismissDisplayAnimated:YES];
+
+    [self _processMediaInfoDictionaries:[NSArray arrayWithObject:info]
+        successBlock:^(NSArray *processedResults, NSString *displayString) {
+            ASSERT([processedResults count] == 1);
+            _WKFileUploadItem *result = [processedResults objectAtIndex:0];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self _chooseFiles:[NSArray arrayWithObject:result.fileURL] displayString:displayString iconImage:result.displayImage];
+            });
+        }
+        failureBlock:^{
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self _cancel];
+            });
+        }
+    ];
+}
+
+- (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMultipleMediaWithInfo:(NSArray *)infos
+{
+    [self _dismissDisplayAnimated:YES];
+
+    [self _processMediaInfoDictionaries:infos
+        successBlock:^(NSArray *processedResults, NSString *displayString) {
+            UIImage *iconImage = nil;
+            NSMutableArray *fileURLs = [NSMutableArray array];
+            for (_WKFileUploadItem *result in processedResults) {
+                NSURL *fileURL = result.fileURL;
+                if (!fileURL)
+                    continue;
+                [fileURLs addObject:result.fileURL];
+                if (!iconImage)
+                    iconImage = result.displayImage;
+            }
+
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self _chooseFiles:fileURLs displayString:displayString iconImage:iconImage];
+            });
+        }
+        failureBlock:^{
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self _cancel];
+            });
+        }
+    ];
+}
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)imagePicker
+{
+    [self _dismissDisplayAnimated:YES];
+    [self _cancel];
+}
+
+#pragma mark - Process UIImagePicker results
+
+- (void)_processMediaInfoDictionaries:(NSArray *)infos successBlock:(void (^)(NSArray *processedResults, NSString *displayString))successBlock failureBlock:(void (^)())failureBlock
+{
+    [self _processMediaInfoDictionaries:infos atIndex:0 processedResults:[NSMutableArray array] processedImageCount:0 processedVideoCount:0 successBlock:successBlock failureBlock:failureBlock];
+}
+
+- (void)_processMediaInfoDictionaries:(NSArray *)infos atIndex:(NSUInteger)index processedResults:(NSMutableArray *)processedResults processedImageCount:(NSUInteger)processedImageCount processedVideoCount:(NSUInteger)processedVideoCount successBlock:(void (^)(NSArray *processedResults, NSString *displayString))successBlock failureBlock:(void (^)())failureBlock
+{
+    NSUInteger count = [infos count];
+    if (index == count) {
+        NSString *displayString = [self _displayStringForPhotos:processedImageCount videos:processedVideoCount];
+        successBlock(processedResults, displayString);
+        return;
+    }
+
+    NSDictionary *info = [infos objectAtIndex:index];
+    ASSERT(index &lt; count);
+    index++;
+
+    auto uploadItemSuccessBlock = ^(_WKFileUploadItem *uploadItem) {
+        NSUInteger newProcessedVideoCount = processedVideoCount + (uploadItem.isVideo ? 1 : 0);
+        NSUInteger newProcessedImageCount = processedImageCount + (uploadItem.isVideo ? 0 : 1);
+        [processedResults addObject:uploadItem];
+        [self _processMediaInfoDictionaries:infos atIndex:index processedResults:processedResults processedImageCount:newProcessedImageCount processedVideoCount:newProcessedVideoCount successBlock:successBlock failureBlock:failureBlock];
+    };
+
+    [self _uploadItemFromMediaInfo:info successBlock:uploadItemSuccessBlock failureBlock:failureBlock];
+}
+
+- (void)_uploadItemFromMediaInfo:(NSDictionary *)info successBlock:(void (^)(_WKFileUploadItem *))successBlock failureBlock:(void (^)())failureBlock
+{
+    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
+
+    // For videos from the existing library or camera, the media URL will give us a file path.
+    if (UTTypeConformsTo((CFStringRef)mediaType, kUTTypeMovie)) {
+        NSURL *mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
+        if (![mediaURL isFileURL]) {
+            LOG_ERROR(&quot;WKFileUploadPanel: Expected media URL to be a file path, it was not&quot;);
+            ASSERT_NOT_REACHED();
+            failureBlock();
+            return;
+        }
+
+        NSString *filePath = [mediaURL path];
+        successBlock(adoptNS([[_WKVideoFileUploadItem alloc] initWithFilePath:filePath mediaURL:mediaURL]).get());
+        return;
+    }
+
+    // For images, we create a temporary file path and use the original image.
+    if (UTTypeConformsTo((CFStringRef)mediaType, kUTTypeImage)) {
+        UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
+        if (!originalImage) {
+            LOG_ERROR(&quot;WKFileUploadPanel: Expected image data but there was none&quot;);
+            ASSERT_NOT_REACHED();
+            failureBlock();
+            return;
+        }
+
+        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            NSString * const kTemporaryDirectoryName = @&quot;WKWebFileUpload&quot;;
+            NSString * const kUploadImageName = @&quot;image.jpg&quot;;
+
+            // Build temporary file path.
+            // FIXME: Should we get the ALAsset for the mediaURL and get the actual filename for the photo
+            // instead of naming each of the individual uploads image.jpg? This won't work for photos
+            // taken with the camera, but would work for photos picked from the library.
+            NSFileManager *fileManager = [NSFileManager defaultManager];
+            NSString *temporaryDirectory = [fileManager _webkit_createTemporaryDirectoryWithTemplatePrefix:kTemporaryDirectoryName];
+            NSString *filePath = [temporaryDirectory stringByAppendingPathComponent:kUploadImageName];
+            if (!filePath) {
+                LOG_ERROR(&quot;WKFileUploadPanel: Failed to create temporary directory to save image&quot;);
+                failureBlock();
+                return;
+            }
+
+            // Compress to JPEG format.
+            // FIXME: Different compression for different devices?
+            // FIXME: Different compression for different UIImage sizes?
+            // FIXME: Should EXIF data be maintained?
+            const CGFloat compression = 0.8;
+            NSData *jpeg = UIImageJPEGRepresentation(originalImage, compression);
+            if (!jpeg) {
+                LOG_ERROR(&quot;WKFileUploadPanel: Failed to create JPEG representation for image&quot;);
+                failureBlock();
+                return;
+            }
+
+            // Save the image to the temporary file.
+            NSError *error = nil;
+            [jpeg writeToFile:filePath options:NSDataWritingAtomic error:&amp;error];
+            if (error) {
+                LOG_ERROR(&quot;WKFileUploadPanel: Error writing image data to temporary file: %@&quot;, error);
+                failureBlock();
+                return;
+            }
+
+            successBlock(adoptNS([[_WKImageFileUploadItem alloc] initWithFilePath:filePath originalImage:originalImage]).get());
+        });
+        return;
+    }
+
+    // Unknown media type.
+    LOG_ERROR(&quot;WKFileUploadPanel: Unexpected media type. Expected image or video, got: %@&quot;, mediaType);
+    failureBlock();
+}
+
+- (NSString *)_displayStringForPhotos:(NSUInteger)imageCount videos:(NSUInteger)videoCount
+{
+    if (!imageCount &amp;&amp; !videoCount)
+        return nil;
+
+    NSString *title;
+    NSString *countString;
+    NSString *imageString;
+    NSString *videoString;
+    NSUInteger numberOfTypes = 2;
+
+    RetainPtr&lt;NSNumberFormatter&gt; countFormatter = adoptNS([[NSNumberFormatter alloc] init]);
+    [countFormatter setLocale:[NSLocale currentLocale]];
+    [countFormatter setGeneratesDecimalNumbers:YES];
+    [countFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
+
+    // Generate the individual counts for each type.
+    switch (imageCount) {
+    case 0:
+        imageString = nil;
+        --numberOfTypes;
+        break;
+    case 1:
+        imageString = WEB_UI_STRING_KEY(&quot;1 Photo&quot;, &quot;1 Photo (file upload on page label for one photo)&quot;, &quot;File Upload single photo label&quot;);
+        break;
+    default:
+        countString = [countFormatter stringFromNumber:@(imageCount)];
+        imageString = [NSString stringWithFormat:WEB_UI_STRING_KEY(&quot;%@ Photos&quot;, &quot;# Photos (file upload on page label for multiple photos)&quot;, &quot;File Upload multiple photos label&quot;), countString];
+        break;
+    }
+
+    switch (videoCount) {
+    case 0:
+        videoString = nil;
+        --numberOfTypes;
+        break;
+    case 1:
+        videoString = WEB_UI_STRING_KEY(&quot;1 Video&quot;, &quot;1 Video (file upload on page label for one video)&quot;, &quot;File Upload single video label&quot;);
+        break;
+    default:
+        countString = [countFormatter stringFromNumber:@(videoCount)];
+        videoString = [NSString stringWithFormat:WEB_UI_STRING_KEY(&quot;%@ Videos&quot;, &quot;# Videos (file upload on page label for multiple videos)&quot;, &quot;File Upload multiple videos label&quot;), countString];
+        break;
+    }
+
+    // Combine into a single result string if needed.
+    switch (numberOfTypes) {
+    case 2:
+        // FIXME: For localization we should build a complete string. We should have a localized string for each different combination.
+        title = [NSString stringWithFormat:WEB_UI_STRING_KEY(&quot;%@ and %@&quot;, &quot;# Photos and # Videos (file upload on page label for image and videos)&quot;, &quot;File Upload images and videos label&quot;), imageString, videoString];
+        break;
+    case 1:
+        title = imageString ? imageString : videoString;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        title = nil;
+        break;
+    }
+
+    return [title lowercaseString];
+}
+
+@end
+
+#endif // PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -1039,6 +1039,8 @@
</span><span class="cx">                 A1C512C9190656E500448914 /* WebQuickLookHandleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C512C7190656E500448914 /* WebQuickLookHandleClient.h */; };
</span><span class="cx">                 A1DF631218E0B7C8003A3E2A /* DownloadClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */; };
</span><span class="cx">                 A1DF631318E0B7C8003A3E2A /* DownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A1DF631118E0B7C8003A3E2A /* DownloadClient.h */; };
</span><ins>+                A58B6F0818FCA733008CBA53 /* WKFileUploadPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = A58B6F0618FCA733008CBA53 /* WKFileUploadPanel.h */; };
+                A58B6F0918FCA733008CBA53 /* WKFileUploadPanel.mm in Sources */ = {isa = PBXBuildFile; fileRef = A58B6F0718FCA733008CBA53 /* WKFileUploadPanel.mm */; };
</ins><span class="cx">                 A5EFD38C16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EFD38B16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A7D792D61767CB6E00881CBE /* ActivityAssertion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */; };
</span><span class="cx">                 A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
</span><span class="lines">@@ -2922,6 +2924,8 @@
</span><span class="cx">                 A1EDD2DB1884B96400BBFE98 /* PluginProcessShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = PluginProcessShim.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SecItemShim.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1EDD2DD1884B9E300BBFE98 /* WebProcessShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebProcessShim.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                A58B6F0618FCA733008CBA53 /* WKFileUploadPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFileUploadPanel.h; path = ios/forms/WKFileUploadPanel.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A58B6F0718FCA733008CBA53 /* WKFileUploadPanel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFileUploadPanel.mm; path = ios/forms/WKFileUploadPanel.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A5EFD38B16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPageVisibilityTypes.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A72D5D7F1236CBA800A88B15 /* WebSerializedScriptValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSerializedScriptValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A7D792D41767CB0900881CBE /* ActivityAssertion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityAssertion.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6526,6 +6530,8 @@
</span><span class="cx">                         children = (
</span><span class="cx">                                 C5FA1ED118E1062200B3F402 /* WKAirPlayRoutePicker.h */,
</span><span class="cx">                                 C5FA1ED218E1062200B3F402 /* WKAirPlayRoutePicker.mm */,
</span><ins>+                                A58B6F0618FCA733008CBA53 /* WKFileUploadPanel.h */,
+                                A58B6F0718FCA733008CBA53 /* WKFileUploadPanel.mm */,
</ins><span class="cx">                                 C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */,
</span><span class="cx">                                 C54256B018BEC18B00DE4179 /* WKFormInputControl.mm */,
</span><span class="cx">                                 C54256B118BEC18B00DE4179 /* WKFormPeripheral.h */,
</span><span class="lines">@@ -6739,6 +6745,7 @@
</span><span class="cx">                                 1AB7D4CA1288AAA700CFD08C /* DownloadProxy.h in Headers */,
</span><span class="cx">                                 373D122D18A4B6EB0066D9CC /* WKWebProcessPlugInFramePrivate.h in Headers */,
</span><span class="cx">                                 1AD25E96167AB08100EA9BCD /* DownloadProxyMap.h in Headers */,
</span><ins>+                                A58B6F0818FCA733008CBA53 /* WKFileUploadPanel.h in Headers */,
</ins><span class="cx">                                 1AB7D61A1288B9D900CFD08C /* DownloadProxyMessages.h in Headers */,
</span><span class="cx">                                 C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */,
</span><span class="cx">                                 BC8452A81162C80900CAB9B5 /* DrawingArea.h in Headers */,
</span><span class="lines">@@ -8458,6 +8465,7 @@
</span><span class="cx">                                 BC111A5A112F4FBB00337BAB /* WebChromeClient.cpp in Sources */,
</span><span class="cx">                                 868160D0187645570021E79D /* WindowServerConnection.mm in Sources */,
</span><span class="cx">                                 3F87B9BD158940120090FF62 /* WebColorChooser.cpp in Sources */,
</span><ins>+                                A58B6F0918FCA733008CBA53 /* WKFileUploadPanel.mm in Sources */,
</ins><span class="cx">                                 F036978815F4BF0500C3A80E /* WebColorPicker.cpp in Sources */,
</span><span class="cx">                                 BC4A628F147312BE006C681A /* WebConnection.cpp in Sources */,
</span><span class="cx">                                 BC4A6291147312BE006C681A /* WebConnectionClient.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebOpenPanelResultListenercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -26,6 +26,8 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WebOpenPanelResultListener.h&quot;
</span><span class="cx"> 
</span><ins>+#include &lt;WebCore/Icon.h&gt;
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;WebOpenPanelResultListener&gt; WebOpenPanelResultListener::create(WebPage* page, PassRefPtr&lt;WebCore::FileChooser&gt; fileChooser)
</span><span class="lines">@@ -48,4 +50,11 @@
</span><span class="cx">     m_fileChooser-&gt;chooseFiles(files);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+void WebOpenPanelResultListener::didChooseFilesWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp; files, const String&amp; displayString, WebCore::Icon* displayIcon)
+{
+    m_fileChooser-&gt;chooseMediaFiles(files, displayString, displayIcon);
+}
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebOpenPanelResultListenerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -29,6 +29,10 @@
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;WebCore/FileChooser.h&gt;
</span><span class="cx"> 
</span><ins>+namespace WebCore {
+class Icon;
+}
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> class WebPage;
</span><span class="lines">@@ -40,6 +44,9 @@
</span><span class="cx"> 
</span><span class="cx">     void disconnectFromPage() { m_page = 0; }
</span><span class="cx">     void didChooseFiles(const Vector&lt;String&gt;&amp;);
</span><ins>+#if PLATFORM(IOS)
+    void didChooseFilesWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp;, const String&amp; displayString, WebCore::Icon*);
+#endif
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebOpenPanelResultListener(WebPage*, PassRefPtr&lt;WebCore::FileChooser&gt;);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -185,6 +185,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> #include &quot;WebVideoFullscreenManager.h&quot;
</span><ins>+#include &lt;CoreGraphics/CoreGraphics.h&gt;
+#include &lt;WebCore/Icon.h&gt;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -3050,6 +3052,25 @@
</span><span class="cx">     m_activePopupMenu-&gt;didChangeSelectedIndex(index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp; files, const String&amp; displayString, const IPC::DataReference&amp; iconData)
+{
+    if (!m_activeOpenPanelResultListener)
+        return;
+
+    RefPtr&lt;Icon&gt; icon;
+    if (!iconData.isEmpty()) {
+        RetainPtr&lt;CFDataRef&gt; dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
+        RetainPtr&lt;CGDataProviderRef&gt; imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
+        RetainPtr&lt;CGImageRef&gt; imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
+        icon = Icon::createIconForImage(imageRef.get());
+    }
+
+    m_activeOpenPanelResultListener-&gt;didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
+    m_activeOpenPanelResultListener = nullptr;
+}
+#endif
+
</ins><span class="cx"> void WebPage::didChooseFilesForOpenPanel(const Vector&lt;String&gt;&amp; files)
</span><span class="cx"> {
</span><span class="cx">     if (!m_activeOpenPanelResultListener)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -959,6 +959,9 @@
</span><span class="cx">     void failedToShowPopupMenu();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector&lt;String&gt;&amp;, const String&amp; displayString, const IPC::DataReference&amp; iconData);
+#endif
</ins><span class="cx">     void didChooseFilesForOpenPanel(const Vector&lt;String&gt;&amp;);
</span><span class="cx">     void didCancelForOpenPanel();
</span><span class="cx"> #if ENABLE(WEB_PROCESS_SANDBOX)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (168179 => 168180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-05-02 19:01:10 UTC (rev 168179)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-05-02 19:28:30 UTC (rev 168180)
</span><span class="lines">@@ -225,6 +225,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Open panel.
</span><ins>+#if PLATFORM(IOS)
+    DidChooseFilesForOpenPanelWithDisplayStringAndIcon(Vector&lt;String&gt; fileURLs, String displayString, IPC::DataReference iconData)
+#endif
</ins><span class="cx">     DidChooseFilesForOpenPanel(Vector&lt;String&gt; fileURLs)
</span><span class="cx">     DidCancelForOpenPanel()
</span><span class="cx"> #if ENABLE(WEB_PROCESS_SANDBOX)
</span></span></pre>
</div>
</div>

</body>
</html>