<!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 <input type="file"> 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 <input> 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 <pecoraro@apple.com>
+
+ [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 <input type="file"> on iOS.
+
</ins><span class="cx"> 2014-05-02 Chris Fleizach <cfleizach@apple.com>
</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 */
+"# Photos (file upload on page label for multiple photos)" = "%@ Photos";
+
+/* File Upload images and videos label */
+"# Photos and # Videos (file upload on page label for image and videos)" = "%@ and %@";
+
+/* File Upload multiple videos label */
+"# Videos (file upload on page label for multiple videos)" = "%@ Videos";
+
</ins><span class="cx"> /* accessibility help text for media controller time value >= 1 day */
</span><span class="cx"> "%1$d days %2$d hours %3$d minutes %4$d seconds" = "%1$d days %2$d hours %3$d minutes %4$d seconds";
</span><span class="cx">
</span><span class="lines">@@ -55,6 +64,12 @@
</span><span class="cx"> /* Present the element <select multiple> when a single <option> is selected (iOS only) */
</span><span class="cx"> "1 Item" = "1 Item";
</span><span class="cx">
</span><ins>+/* File Upload single photo label */
+"1 Photo (file upload on page label for one photo)" = "1 Photo";
+
+/* File Upload single video label */
+"1 Video (file upload on page label for one video)" = "1 Video";
+
</ins><span class="cx"> /* Menu item title for KEYGEN pop-up menu */
</span><span class="cx"> "1024 (Medium Grade)" = "1024 (Medium Grade)";
</span><span class="cx">
</span><span class="lines">@@ -94,6 +109,9 @@
</span><span class="cx"> /* Undo action name */
</span><span class="cx"> "Bold (Undo action name)" = "Bold";
</span><span class="cx">
</span><ins>+/* File Upload alert sheet button string to cancel */
+"Cancel (file upload action sheet)" = "Cancel";
+
</ins><span class="cx"> /* Title for Cancel button label in button bar */
</span><span class="cx"> "Cancel button label in button bar" = "Cancel";
</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"> "Pause" = "Pause";
</span><span class="cx">
</span><ins>+/* File Upload alert sheet button string for choosing an existing media item from the Photo Library */
+"Photo Library (file upload action sheet)" = "Photo Library";
+
</ins><span class="cx"> /* Media Play context menu item */
</span><span class="cx"> "Play" = "Play";
</span><span class="cx">
</span><span class="lines">@@ -526,6 +547,15 @@
</span><span class="cx"> /* Undo action name */
</span><span class="cx"> "Superscript (Undo action name)" = "Superscript";
</span><span class="cx">
</span><ins>+/* File Upload alert sheet camera button string for taking only photos */
+"Take Photo (file upload action sheet)" = "Take Photo";
+
+/* File Upload alert sheet camera button string for taking photos or videos */
+"Take Photo or Video (file upload action sheet)" = "Take Photo or Video";
+
+/* File Upload alert sheet camera button string for taking only videos */
+"Take Video (file upload action sheet)" = "Take Video";
+
</ins><span class="cx"> /* Text Replacement context menu item */
</span><span class="cx"> "Text Replacement" = "Text Replacement";
</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 <pecoraro@apple.com>
+
+ [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 <input> 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 <simon.fraser@apple.com>
</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 "BaseTarget.xcconfig"
</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<WebOpenPanelParameters> create(const WebCore::FileChooserSettings&);
</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<API::Array> acceptMIMETypes() const;
</span><span class="cx"> PassRefPtr<API::Array> 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&) = 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 "WebOpenPanelResultListenerProxy.h"
</span><span class="cx">
</span><span class="cx"> #include "APIArray.h"
</span><ins>+#include "APIString.h"
</ins><span class="cx"> #include "WebPageProxy.h"
</span><span class="cx"> #include <WebCore/URL.h>
</span><span class="cx"> #include <wtf/Vector.h>
</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<String> filePathsFromFileURLs(const API::Array& fileURLs)
</ins><span class="cx"> {
</span><del>- if (!m_page)
- return;
</del><ins>+ Vector<String> filePaths;
</ins><span class="cx">
</span><del>- size_t size = fileURLsArray->size();
-
- Vector<String> 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 < size; ++i) {
</span><del>- API::URL* apiURL = fileURLsArray->at<API::URL>(i);
- if (apiURL) {
- URL url(URL(), apiURL->string());
- filePaths.uncheckedAppend(url.fileSystemPath());
- }
</del><ins>+ API::URL* apiURL = fileURLs.at<API::URL>(i);
+ if (apiURL)
+ filePaths.uncheckedAppend(URL(URL(), apiURL->string()).fileSystemPath());
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- m_page->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->didChooseFilesForOpenPanelWithDisplayStringAndIcon(filePathsFromFileURLs(*fileURLsArray), displayString ? displayString->string() : String(), iconImageData);
+}
+#endif
+
+void WebOpenPanelResultListenerProxy::chooseFiles(API::Array* fileURLsArray)
+{
+ if (!m_page)
+ return;
+
+ m_page->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->responsivenessTimer()->stop();
</span><span class="cx">
</span><del>- if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
- didCancelForOpenPanel();
</del><ins>+ if (!m_uiClient->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<String>& fileURLs, const String& displayString, const API::Data* iconData)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData->dataReference() : IPC::DataReference()), m_pageID);
+
+ m_openPanelResultListener->invalidate();
+ m_openPanelResultListener = nullptr;
+}
+#endif
+
</ins><span class="cx"> void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& 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<String>&, const String& displayString, const API::Data* iconData);
+#endif
</ins><span class="cx"> void didChooseFilesForOpenPanel(const Vector<String>&);
</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& 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 "GestureTypes.h"
</span><span class="cx"> #import "InteractionInformationAtPosition.h"
</span><span class="cx"> #import "WKAirPlayRoutePicker.h"
</span><ins>+#import "WKFileUploadPanel.h"
</ins><span class="cx"> #import "WKFormPeripheral.h"
</span><span class="cx"> #import <UIKit/UITextInput_Private.h>
</span><span class="cx"> #import <UIKit/UIView.h>
</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<WKActionSheetAssistant> _actionSheetAssistant;
</span><span class="cx"> RetainPtr<WKAirPlayRoutePicker> _airPlayRoutePicker;
</span><span class="cx"> RetainPtr<WKFormInputSession> _formInputSession;
</span><ins>+ RetainPtr<WKFileUploadPanel> _fileUploadPanel;
</ins><span class="cx">
</span><span class="cx"> std::unique_ptr<WebKit::SmartMagnificationController> _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<NSObject<WKFormPeripheral>> _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) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol>
</del><ins>+@interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate>
</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& positionInformation;
</span><span class="cx"> @property (nonatomic, readonly) const WebKit::WKAutoCorrectionData& 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&)elementRect;
</span><ins>+- (void)_showRunOpenPanel:(WebKit::WebOpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
</ins><span class="cx"> - (void)accessoryDone;
</span><span class="cx"> - (Vector<WebKit::WKOptionItem>&) 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 "NativeWebKeyboardEvent.h"
</span><span class="cx"> #import "NativeWebTouchEvent.h"
</span><span class="cx"> #import "SmartMagnificationController.h"
</span><ins>+#import "WKActionSheetAssistant.h"
+#import "WKFormInputControl.h"
+#import "WKFormSelectControl.h"
+#import "WKWebViewPrivate.h"
</ins><span class="cx"> #import "WebEvent.h"
</span><span class="cx"> #import "WebIOSEventFactory.h"
</span><span class="cx"> #import "WebPageMessages.h"
</span><span class="cx"> #import "WebProcessProxy.h"
</span><del>-#import "WKActionSheetAssistant.h"
-#import "WKFormInputControl.h"
-#import "WKFormSelectControl.h"
-#import "WKWebViewPrivate.h"
</del><span class="cx"> #import "_WKFormDelegate.h"
</span><span class="cx"> #import "_WKFormInputSession.h"
</span><span class="cx"> #import <DataDetectorsUI/DDDetectionController.h>
</span><span class="cx"> #import <TextInput/TI_NSStringExtras.h>
</span><del>-#import <UIKit/_UIHighlightView.h>
-#import <UIKit/_UIWebHighlightLongPressGestureRecognizer.h>
</del><span class="cx"> #import <UIKit/UIFont_Private.h>
</span><span class="cx"> #import <UIKit/UIGestureRecognizer_Private.h>
</span><span class="cx"> #import <UIKit/UIKeyboardImpl.h>
</span><span class="lines">@@ -54,6 +52,8 @@
</span><span class="cx"> #import <UIKit/UITapGestureRecognizer_Private.h>
</span><span class="cx"> #import <UIKit/UITextInteractionAssistant_Private.h>
</span><span class="cx"> #import <UIKit/UIWebDocumentView.h> // FIXME: should not include this header.
</span><ins>+#import <UIKit/_UIHighlightView.h>
+#import <UIKit/_UIWebHighlightLongPressGestureRecognizer.h>
</ins><span class="cx"> #import <WebCore/Color.h>
</span><span class="cx"> #import <WebCore/FloatQuad.h>
</span><span class="cx"> #import <WebCore/NotImplemented.h>
</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&)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->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->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->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->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 <UIKit/UIViewController.h>
+
+@class WKContentView;
+@protocol WKFileUploadPanelDelegate;
+
+namespace WebKit {
+class WebOpenPanelParameters;
+class WebOpenPanelResultListenerProxy;
+}
+
+@interface WKFileUploadPanel : UIViewController
+@property (nonatomic, assign) id <WKFileUploadPanelDelegate> delegate;
+- (instancetype)initWithView:(WKContentView *)view;
+- (void)presentWithParameters:(WebKit::WebOpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
+- (void)dismiss;
+@end
+
+@protocol WKFileUploadPanelDelegate <NSObject>
+@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 "config.h"
+#import "WKFileUploadPanel.h"
+
+#if PLATFORM(IOS)
+
+#import "APIArray.h"
+#import "APIData.h"
+#import "APIString.h"
+#import "WKContentViewInteraction.h"
+#import "WKData.h"
+#import "WKStringCF.h"
+#import "WKURLCF.h"
+#import "WebOpenPanelParameters.h"
+#import "WebOpenPanelResultListenerProxy.h"
+#import "WebPageProxy.h"
+#import <AVFoundation/AVFoundation.h>
+#import <CoreMedia/CoreMedia.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+#import <UIKit/UIAlertController_Private.h>
+#import <UIKit/UIApplication_Private.h>
+#import <UIKit/UIImagePickerController_Private.h>
+#import <UIKit/UIImage_Private.h>
+#import <UIKit/UIViewController_Private.h>
+#import <UIKit/UIWindow_Private.h>
+#import <WebCore/LocalizedStrings.h>
+#import <WebCore/SoftLinking.h>
+#import <WebKit/WebNSFileManagerExtras.h>
+#import <wtf/RetainPtr.h>
+
+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 < 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<NSString> _filePath;
+ RetainPtr<UIImage> _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<NSString> _filePath;
+ RetainPtr<NSURL> _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<AVURLAsset> asset = adoptNS([[AVURLAsset_class alloc] initWithURL:_mediaURL.get() options:nil]);
+ RetainPtr<AVAssetImageGenerator> generator = adoptNS([[AVAssetImageGenerator_class alloc] initWithAsset:asset.get()]);
+ [generator setAppliesPreferredTrackTransform:YES];
+
+ NSError *error = nil;
+ RetainPtr<CGImageRef> imageRef = adoptCF([generator copyCGImageAtTime:kCMTimeZero actualTime:nil error:&error]);
+ if (error) {
+ LOG_ERROR("_WKVideoFileUploadItem: Error creating image for video: %@", _mediaURL.get());
+ return nil;
+ }
+
+ RetainPtr<UIImage> image = adoptNS([[UIImage alloc] initWithCGImage:imageRef.get()]);
+ return thumbnailSizedImageForImage(image.get());
+}
+
+@end
+
+
+#pragma mark - WKFileUploadPanel
+
+@interface WKFileUploadPanel () <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
+@end
+
+@implementation WKFileUploadPanel {
+ WKContentView *_view;
+ WebKit::WebOpenPanelResultListenerProxy* _listener;
+ RetainPtr<NSArray> _mimeTypes;
+ CGPoint _interactionPoint;
+ BOOL _allowMultipleFiles;
+ BOOL _usingCamera;
+ RetainPtr<UIImagePickerController> _imagePicker;
+ RetainPtr<UIAlertController> _actionSheetController;
+ RetainPtr<UIViewController> _presentationViewController; // iPhone always. iPad for Fullscreen Camera.
+ RetainPtr<UIPopoverController> _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->cancel();
+ [self _dispatchDidDismiss];
+}
+
+- (void)_chooseFiles:(NSArray *)fileURLs displayString:(NSString *)displayString iconImage:(UIImage *)iconImage
+{
+ NSUInteger count = [fileURLs count];
+ if (!count) {
+ [self _cancel];
+ return;
+ }
+
+ Vector<RefPtr<API::Object>> urls;
+ urls.reserveInitialCapacity(count);
+ for (NSURL *fileURL in fileURLs)
+ urls.uncheckedAppend(adoptRef(toImpl(WKURLCreateWithCFURL((CFURLRef)fileURL))));
+ RefPtr<API::Array> fileURLsRef = API::Array::create(std::move(urls));
+
+ NSData *jpeg = UIImageJPEGRepresentation(iconImage, 1.0);
+ RefPtr<API::Data> iconImageDataRef = adoptRef(toImpl(WKDataCreate(reinterpret_cast<const unsigned char*>([jpeg bytes]), [jpeg length])));
+
+ RefPtr<API::String> displayStringRef = adoptRef(toImpl(WKStringCreateWithCFString((CFStringRef)displayString)));
+
+ _listener->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->allowMultipleFiles();
+ _interactionPoint = [_view lastInteractionLocation];
+
+ RefPtr<API::Array> acceptMimeTypes = parameters->acceptMIMETypes();
+ NSMutableArray *mimeTypes = [NSMutableArray arrayWithCapacity:acceptMimeTypes->size()];
+ for (const auto& mimeType : acceptMimeTypes->elementsOfType<API::String>())
+ [mimeTypes addObject:mimeType->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 "image/*" and "video/*" strings.
+ // We support these and go a step further, if the MIME type starts with
+ // "image/" or "video/" we adjust the picker's image or video filters.
+ // So, "image/jpeg" would make the picker display all images types.
+ NSMutableSet *mediaTypes = [NSMutableSet set];
+ for (NSString *mimeType in _mimeTypes.get()) {
+ if (stringHasPrefixCaseInsensitive(mimeType, @"image/"))
+ [mediaTypes addObject:(NSString *)kUTTypeImage];
+ else if (stringHasPrefixCaseInsensitive(mimeType, @"video/"))
+ [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("Photo Library", "Photo Library (file upload action sheet)", "File Upload alert sheet button string for choosing an existing media item from the Photo Library");
+ NSString *cancelString = WEB_UI_STRING_KEY("Cancel", "Cancel (file upload action sheet)", "File Upload alert sheet button string to cancel");
+
+ // 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 && containsVideoMediaType)
+ cameraString = WEB_UI_STRING_KEY("Take Photo or Video", "Take Photo or Video (file upload action sheet)", "File Upload alert sheet camera button string for taking photos or videos");
+ else if (containsVideoMediaType)
+ cameraString = WEB_UI_STRING_KEY("Take Video", "Take Video (file upload action sheet)", "File Upload alert sheet camera button string for taking only videos");
+ else
+ cameraString = WEB_UI_STRING_KEY("Take Photo", "Take Photo (file upload action sheet)", "File Upload alert sheet camera button string for taking only photos");
+
+ _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() && 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 < 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("WKFileUploadPanel: Expected media URL to be a file path, it was not");
+ 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("WKFileUploadPanel: Expected image data but there was none");
+ ASSERT_NOT_REACHED();
+ failureBlock();
+ return;
+ }
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSString * const kTemporaryDirectoryName = @"WKWebFileUpload";
+ NSString * const kUploadImageName = @"image.jpg";
+
+ // 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("WKFileUploadPanel: Failed to create temporary directory to save image");
+ 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("WKFileUploadPanel: Failed to create JPEG representation for image");
+ failureBlock();
+ return;
+ }
+
+ // Save the image to the temporary file.
+ NSError *error = nil;
+ [jpeg writeToFile:filePath options:NSDataWritingAtomic error:&error];
+ if (error) {
+ LOG_ERROR("WKFileUploadPanel: Error writing image data to temporary file: %@", error);
+ failureBlock();
+ return;
+ }
+
+ successBlock(adoptNS([[_WKImageFileUploadItem alloc] initWithFilePath:filePath originalImage:originalImage]).get());
+ });
+ return;
+ }
+
+ // Unknown media type.
+ LOG_ERROR("WKFileUploadPanel: Unexpected media type. Expected image or video, got: %@", mediaType);
+ failureBlock();
+}
+
+- (NSString *)_displayStringForPhotos:(NSUInteger)imageCount videos:(NSUInteger)videoCount
+{
+ if (!imageCount && !videoCount)
+ return nil;
+
+ NSString *title;
+ NSString *countString;
+ NSString *imageString;
+ NSString *videoString;
+ NSUInteger numberOfTypes = 2;
+
+ RetainPtr<NSNumberFormatter> 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("1 Photo", "1 Photo (file upload on page label for one photo)", "File Upload single photo label");
+ break;
+ default:
+ countString = [countFormatter stringFromNumber:@(imageCount)];
+ imageString = [NSString stringWithFormat:WEB_UI_STRING_KEY("%@ Photos", "# Photos (file upload on page label for multiple photos)", "File Upload multiple photos label"), countString];
+ break;
+ }
+
+ switch (videoCount) {
+ case 0:
+ videoString = nil;
+ --numberOfTypes;
+ break;
+ case 1:
+ videoString = WEB_UI_STRING_KEY("1 Video", "1 Video (file upload on page label for one video)", "File Upload single video label");
+ break;
+ default:
+ countString = [countFormatter stringFromNumber:@(videoCount)];
+ videoString = [NSString stringWithFormat:WEB_UI_STRING_KEY("%@ Videos", "# Videos (file upload on page label for multiple videos)", "File Upload multiple videos label"), 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("%@ and %@", "# Photos and # Videos (file upload on page label for image and videos)", "File Upload images and videos label"), 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 = "<group>"; };
</span><span class="cx">                 A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SecItemShim.xcconfig; sourceTree = "<group>"; };
</span><span class="cx">                 A1EDD2DD1884B9E300BBFE98 /* WebProcessShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebProcessShim.xcconfig; sourceTree = "<group>"; };
</span><ins>+                A58B6F0618FCA733008CBA53 /* WKFileUploadPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFileUploadPanel.h; path = ios/forms/WKFileUploadPanel.h; sourceTree = "<group>"; };
+                A58B6F0718FCA733008CBA53 /* WKFileUploadPanel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFileUploadPanel.mm; path = ios/forms/WKFileUploadPanel.mm; sourceTree = "<group>"; };
</ins><span class="cx">                 A5EFD38B16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPageVisibilityTypes.h; sourceTree = "<group>"; };
</span><span class="cx">                 A72D5D7F1236CBA800A88B15 /* WebSerializedScriptValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSerializedScriptValue.h; sourceTree = "<group>"; };
</span><span class="cx">                 A7D792D41767CB0900881CBE /* ActivityAssertion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityAssertion.h; sourceTree = "<group>"; };
</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 "config.h"
</span><span class="cx"> #include "WebOpenPanelResultListener.h"
</span><span class="cx">
</span><ins>+#include <WebCore/Icon.h>
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx">
</span><span class="cx"> PassRefPtr<WebOpenPanelResultListener> WebOpenPanelResultListener::create(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
</span><span class="lines">@@ -48,4 +50,11 @@
</span><span class="cx"> m_fileChooser->chooseFiles(files);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void WebOpenPanelResultListener::didChooseFilesWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, WebCore::Icon* displayIcon)
+{
+ m_fileChooser->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 <wtf/RefCounted.h>
</span><span class="cx"> #include <WebCore/FileChooser.h>
</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<String>&);
</span><ins>+#if PLATFORM(IOS)
+ void didChooseFilesWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, WebCore::Icon*);
+#endif
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> WebOpenPanelResultListener(WebPage*, PassRefPtr<WebCore::FileChooser>);
</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 "WebVideoFullscreenManager.h"
</span><ins>+#include <CoreGraphics/CoreGraphics.h>
+#include <WebCore/Icon.h>
</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->didChangeSelectedIndex(index);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, const IPC::DataReference& iconData)
+{
+ if (!m_activeOpenPanelResultListener)
+ return;
+
+ RefPtr<Icon> icon;
+ if (!iconData.isEmpty()) {
+ RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
+ RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
+ RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
+ icon = Icon::createIconForImage(imageRef.get());
+ }
+
+ m_activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
+ m_activeOpenPanelResultListener = nullptr;
+}
+#endif
+
</ins><span class="cx"> void WebPage::didChooseFilesForOpenPanel(const Vector<String>& 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<String>&, const String& displayString, const IPC::DataReference& iconData);
+#endif
</ins><span class="cx"> void didChooseFilesForOpenPanel(const Vector<String>&);
</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<String> fileURLs, String displayString, IPC::DataReference iconData)
+#endif
</ins><span class="cx"> DidChooseFilesForOpenPanel(Vector<String> fileURLs)
</span><span class="cx"> DidCancelForOpenPanel()
</span><span class="cx"> #if ENABLE(WEB_PROCESS_SANDBOX)
</span></span></pre>
</div>
</div>
</body>
</html>