Title: [181476] trunk/Source/WebKit2
Revision
181476
Author
[email protected]
Date
2015-03-13 01:08:56 -0700 (Fri, 13 Mar 2015)

Log Message

Use UIDocumentMenuViewController to allow selection of files from
iCloud Drive in WKFileUploadPanel

Part of <https://bugs.webkit.org/show_bug.cgi?id=142596> WebKit on
iOS should support file upload from iCloud Drive
<rdar://problem/12178991>

Reviewed by Andy Estes.

* Platform/spi/ios/UIKitSPI.h:
Include UIDocumentMenuViewController_Private.h if it exists. If not,
declare this new SPI.

* UIProcess/ios/forms/WKFileUploadPanel.mm:
(fallbackIconForFile):
Create a UIDocumentInteractionController for the file, and return a
thumbnail image from its smallest icon.

(iconForImageFile):
If we can get a UIImage from the file, create a thumbnail from it.
Otherwise, call fallbackIconForFile().

(iconForVideoFile):
Code moved from -[_WKVideoFileUploadItem displayImage].

(iconForFile):
Get the file's extension, and get the extension's preferred UTI. If the
UTI is an image type, call iconForImageFile(). If it's a video type,
call iconForVideoFile(). Otherwise, return the fallback icon.

(-[_WKFileUploadItem initWithFileURL:]):
Added an initializer that takes a file URL.

(-[_WKFileUploadItem fileURL]):
(-[_WKImageFileUploadItem initWithFileURL:originalImage:]):
(-[_WKVideoFileUploadItem displayImage]):
(WKFileUploadPanel):
Inherit from UIDocumentPickerDelegate and UIDocumentMenuDelegate. Add
an ivar for the document menu controller.

(-[WKFileUploadPanel dealloc]):
(-[WKFileUploadPanel presentWithParameters:resultListener:]):
If instances of UIDocumentMenuViewController respond to
-_setIgnoreApplicationEntitlementForImport:, meaning we can disable the
assertion that the current app has the iCloud Documents entitlement,
then show the document picker menu. Otherwise, show the current source
selection UI. The runtime check will be removed when a newer UIKit is
available.

(UTIsForMIMETypes):
Return the UTIs for the <input> element's "accept" attribute's MIME
type list.

(-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
Call UTIsForMIMETypes(). Fall back to available source types for this
picker type.

(-[WKFileUploadPanel _documentPickerMenuMediaTypes]):
Call UTIsForMIMETypes(). Fall back to the all-encompassing
"public.item" UTI.

(-[WKFileUploadPanel _photoLibraryButtonLabel]):
(-[WKFileUploadPanel _cameraButtonLabel]):
Factored out of -_showMediaSourceSelectionSheet. Return the
appropriate label for the camera button, based on whether it can take a
photo or video, or return nil if the camera is not available.

(-[WKFileUploadPanel _showMediaSourceSelectionSheet]):
Changed to use -_cameraButtonLabel and
-_presentForCurrentInterfaceIdiom:.

(-[WKFileUploadPanel _showDocumentPickerMenu]):
Create a UIDocumentMenuViewController, and populate it with options to
open the photo library or take a picture or video. If iCloud Drive or
other document sources are available, they will be added automatically.

(-[WKFileUploadPanel _presentForCurrentInterfaceIdiom:]):
(-[WKFileUploadPanel documentMenu:didPickDocumentPicker:]):
(-[WKFileUploadPanel documentMenuWasCancelled:]):
(-[WKFileUploadPanel documentPicker:didPickDocumentAtURL:]):
(-[WKFileUploadPanel documentPickerWasCancelled:]):
(-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):

(-[_WKImageFileUploadItem initWithFilePath:originalImage:]): Deleted.
(-[_WKImageFileUploadItem fileURL]): Deleted.
(-[_WKVideoFileUploadItem initWithFilePath:mediaURL:]): Deleted.
(-[_WKVideoFileUploadItem fileURL]): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (181475 => 181476)


--- trunk/Source/WebKit2/ChangeLog	2015-03-13 07:52:39 UTC (rev 181475)
+++ trunk/Source/WebKit2/ChangeLog	2015-03-13 08:08:56 UTC (rev 181476)
@@ -1,3 +1,93 @@
+2015-03-12  Jon Honeycutt  <[email protected]>
+
+        Use UIDocumentMenuViewController to allow selection of files from
+        iCloud Drive in WKFileUploadPanel
+
+        Part of <https://bugs.webkit.org/show_bug.cgi?id=142596> WebKit on
+        iOS should support file upload from iCloud Drive
+        <rdar://problem/12178991>
+
+        Reviewed by Andy Estes.
+
+        * Platform/spi/ios/UIKitSPI.h:
+        Include UIDocumentMenuViewController_Private.h if it exists. If not,
+        declare this new SPI.
+
+        * UIProcess/ios/forms/WKFileUploadPanel.mm:
+        (fallbackIconForFile):
+        Create a UIDocumentInteractionController for the file, and return a
+        thumbnail image from its smallest icon.
+
+        (iconForImageFile):
+        If we can get a UIImage from the file, create a thumbnail from it.
+        Otherwise, call fallbackIconForFile().
+
+        (iconForVideoFile):
+        Code moved from -[_WKVideoFileUploadItem displayImage].
+
+        (iconForFile):
+        Get the file's extension, and get the extension's preferred UTI. If the
+        UTI is an image type, call iconForImageFile(). If it's a video type,
+        call iconForVideoFile(). Otherwise, return the fallback icon.
+
+        (-[_WKFileUploadItem initWithFileURL:]):
+        Added an initializer that takes a file URL.
+
+        (-[_WKFileUploadItem fileURL]):
+        (-[_WKImageFileUploadItem initWithFileURL:originalImage:]):
+        (-[_WKVideoFileUploadItem displayImage]):
+        (WKFileUploadPanel):
+        Inherit from UIDocumentPickerDelegate and UIDocumentMenuDelegate. Add
+        an ivar for the document menu controller.
+
+        (-[WKFileUploadPanel dealloc]):
+        (-[WKFileUploadPanel presentWithParameters:resultListener:]):
+        If instances of UIDocumentMenuViewController respond to
+        -_setIgnoreApplicationEntitlementForImport:, meaning we can disable the
+        assertion that the current app has the iCloud Documents entitlement,
+        then show the document picker menu. Otherwise, show the current source
+        selection UI. The runtime check will be removed when a newer UIKit is
+        available.
+
+        (UTIsForMIMETypes):
+        Return the UTIs for the <input> element's "accept" attribute's MIME
+        type list.
+
+        (-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
+        Call UTIsForMIMETypes(). Fall back to available source types for this
+        picker type.
+
+        (-[WKFileUploadPanel _documentPickerMenuMediaTypes]):
+        Call UTIsForMIMETypes(). Fall back to the all-encompassing
+        "public.item" UTI.
+
+        (-[WKFileUploadPanel _photoLibraryButtonLabel]):
+        (-[WKFileUploadPanel _cameraButtonLabel]):
+        Factored out of -_showMediaSourceSelectionSheet. Return the
+        appropriate label for the camera button, based on whether it can take a
+        photo or video, or return nil if the camera is not available.
+
+        (-[WKFileUploadPanel _showMediaSourceSelectionSheet]):
+        Changed to use -_cameraButtonLabel and
+        -_presentForCurrentInterfaceIdiom:.
+
+        (-[WKFileUploadPanel _showDocumentPickerMenu]):
+        Create a UIDocumentMenuViewController, and populate it with options to
+        open the photo library or take a picture or video. If iCloud Drive or
+        other document sources are available, they will be added automatically.
+
+        (-[WKFileUploadPanel _presentForCurrentInterfaceIdiom:]):
+        (-[WKFileUploadPanel documentMenu:didPickDocumentPicker:]):
+        (-[WKFileUploadPanel documentMenuWasCancelled:]):
+        (-[WKFileUploadPanel documentPicker:didPickDocumentAtURL:]):
+        (-[WKFileUploadPanel documentPickerWasCancelled:]):
+        (-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):
+
+        (-[_WKImageFileUploadItem initWithFilePath:originalImage:]): Deleted.
+        (-[_WKImageFileUploadItem fileURL]): Deleted.
+        (-[_WKVideoFileUploadItem initWithFilePath:mediaURL:]): Deleted.
+        (-[_WKVideoFileUploadItem fileURL]): Deleted.
+
 2015-03-11  Enrica Casucci  <[email protected]>
 
         Adopt new API for keyboard event handling.

Modified: trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h (181475 => 181476)


--- trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h	2015-03-13 07:52:39 UTC (rev 181475)
+++ trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h	2015-03-13 08:08:56 UTC (rev 181476)
@@ -69,8 +69,17 @@
 #import <UIKit/_UINavigationInteractiveTransition.h>
 #import <UIKit/_UINavigationParallaxTransition.h>
 
+// FIXME: Unconditionally include this file when a new SDK is available. <rdar://problem/20150072>
+#if defined(__has_include) && __has_include(<UIKit/UIDocumentMenuViewController_Private.h>)
+#import <UIKit/UIDocumentMenuViewController_Private.h>
 #else
+@interface UIDocumentMenuViewController (Details)
+@property (nonatomic, assign, setter = _setIgnoreApplicationEntitlementForImport:, getter = _ignoreApplicationEntitlementForImport) BOOL _ignoreApplicationEntitlementForImport;
+@end
+#endif
 
+#else
+
 @interface UIAlertController (Details)
 - (void)_addActionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(void))handler;
 - (void)_addActionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(void))handler shouldDismissHandler:(BOOL (^)(void))shouldDismissHandler;
@@ -658,6 +667,10 @@
 @property (nonatomic) BOOL inputViewObeysDOMFocus;
 @end
 
+@interface UIDocumentMenuViewController (Details)
+@property (nonatomic, assign, setter = _setIgnoreApplicationEntitlementForImport:, getter = _ignoreApplicationEntitlementForImport) BOOL _ignoreApplicationEntitlementForImport;
+@end
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
 @interface UIView (IPI)

Modified: trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm (181475 => 181476)


--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm	2015-03-13 07:52:39 UTC (rev 181475)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFileUploadPanel.mm	2015-03-13 08:08:56 UTC (rev 181476)
@@ -57,9 +57,8 @@
 SOFT_LINK_CONSTANT(CoreMedia, kCMTimeZero, CMTime);
 #define kCMTimeZero getkCMTimeZero()
 
+#pragma mark - Icon generation
 
-#pragma mark - _WKFileUploadItem
-
 static CGRect squareCropRectForSize(CGSize size)
 {
     CGFloat smallerSide = MIN(size.width, size.height);
@@ -105,15 +104,88 @@
     return resultImage;
 }
 
+static UIImage* fallbackIconForFile(NSURL *file)
+{
+    ASSERT_ARG(file, [file isFileURL]);
 
+    UIDocumentInteractionController *interactionController = [UIDocumentInteractionController interactionControllerWithURL:file];
+    return thumbnailSizedImageForImage(interactionController.icons[0]);
+}
+
+static UIImage* iconForImageFile(NSURL *file)
+{
+    ASSERT_ARG(file, [file isFileURL]);
+
+    if (UIImage *image = [UIImage imageWithContentsOfFile:file.path])
+        return thumbnailSizedImageForImage(image);
+
+    LOG_ERROR("WKFileUploadPanel: Error creating thumbnail image for image: %@", file);
+    return fallbackIconForFile(file);
+}
+
+static UIImage* iconForVideoFile(NSURL *file)
+{
+    ASSERT_ARG(file, [file isFileURL]);
+
+    RetainPtr<AVURLAsset> asset = adoptNS([allocAVURLAssetInstance() initWithURL:file options:nil]);
+    RetainPtr<AVAssetImageGenerator> generator = adoptNS([allocAVAssetImageGeneratorInstance() initWithAsset:asset.get()]);
+    [generator setAppliesPreferredTrackTransform:YES];
+
+    NSError *error = nil;
+    RetainPtr<CGImageRef> imageRef = adoptCF([generator copyCGImageAtTime:kCMTimeZero actualTime:nil error:&error]);
+    if (!imageRef) {
+        LOG_ERROR("WKFileUploadPanel: Error creating image for video '%@': %@", file, error);
+        return fallbackIconForFile(file);
+    }
+
+    RetainPtr<UIImage> image = adoptNS([[UIImage alloc] initWithCGImage:imageRef.get()]);
+    return thumbnailSizedImageForImage(image.get());
+}
+
+static UIImage* iconForFile(NSURL *file)
+{
+    ASSERT_ARG(file, [file isFileURL]);
+
+    NSString *fileExtension = file.pathExtension;
+    if (!fileExtension.length)
+        return nil;
+
+    RetainPtr<CFStringRef> fileUTI = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)fileExtension, 0));
+
+    if (UTTypeConformsTo(fileUTI.get(), kUTTypeImage))
+        return iconForImageFile(file);
+
+    if (UTTypeConformsTo(fileUTI.get(), kUTTypeMovie))
+        return iconForVideoFile(file);
+
+    return fallbackIconForFile(file);
+}
+
+
+#pragma mark - _WKFileUploadItem
+
 @interface _WKFileUploadItem : NSObject
+- (instancetype)initWithFileURL:(NSURL *)fileURL;
 @property (nonatomic, readonly, getter=isVideo) BOOL video;
 @property (nonatomic, readonly) NSURL *fileURL;
 @property (nonatomic, readonly) UIImage *displayImage;
 @end
 
-@implementation _WKFileUploadItem
+@implementation _WKFileUploadItem {
+    RetainPtr<NSURL> _fileURL;
+}
 
+- (instancetype)initWithFileURL:(NSURL *)fileURL
+{
+    if (!(self = [super init]))
+        return nil;
+
+    ASSERT([fileURL isFileURL]);
+    ASSERT([[NSFileManager defaultManager] fileExistsAtPath:fileURL.path]);
+    _fileURL = fileURL;
+    return self;
+}
+
 - (BOOL)isVideo
 {
     ASSERT_NOT_REACHED();
@@ -122,8 +194,7 @@
 
 - (NSURL *)fileURL
 {
-    ASSERT_NOT_REACHED();
-    return nil;
+    return _fileURL.get();
 }
 
 - (UIImage *)displayImage
@@ -136,19 +207,18 @@
 
 
 @interface _WKImageFileUploadItem : _WKFileUploadItem
-- (instancetype)initWithFilePath:(NSString *)filePath originalImage:(UIImage *)originalImage;
+- (instancetype)initWithFileURL:(NSURL *)fileURL originalImage:(UIImage *)originalImage;
 @end
 
 @implementation _WKImageFileUploadItem {
-    RetainPtr<NSString> _filePath;
     RetainPtr<UIImage> _originalImage;
 }
 
-- (instancetype)initWithFilePath:(NSString *)filePath originalImage:(UIImage *)originalImage
+- (instancetype)initWithFileURL:(NSURL *)fileURL originalImage:(UIImage *)originalImage
 {
-    if (!(self = [super init]))
+    if (!(self = [super initWithFileURL:fileURL]))
         return nil;
-    _filePath = filePath;
+
     _originalImage = originalImage;
     return self;
 }
@@ -158,11 +228,6 @@
     return NO;
 }
 
-- (NSURL *)fileURL
-{
-    return [NSURL fileURLWithPath:_filePath.get()];
-}
-
 - (UIImage *)displayImage
 {
     return thumbnailSizedImageForImage(_originalImage.get());
@@ -172,48 +237,18 @@
 
 
 @interface _WKVideoFileUploadItem : _WKFileUploadItem
-- (instancetype)initWithFilePath:(NSString *)filePath mediaURL:(NSURL *)mediaURL;
 @end
 
-@implementation _WKVideoFileUploadItem {
-    RetainPtr<NSString> _filePath;
-    RetainPtr<NSURL> _mediaURL;
-}
+@implementation _WKVideoFileUploadItem
 
-- (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([allocAVURLAssetInstance() initWithURL:_mediaURL.get() options:nil]);
-    RetainPtr<AVAssetImageGenerator> generator = adoptNS([allocAVAssetImageGeneratorInstance() 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());
+    return iconForVideoFile(self.fileURL);
 }
 
 @end
@@ -221,7 +256,7 @@
 
 #pragma mark - WKFileUploadPanel
 
-@interface WKFileUploadPanel () <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
+@interface WKFileUploadPanel () <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIDocumentPickerDelegate, UIDocumentMenuDelegate>
 @end
 
 @implementation WKFileUploadPanel {
@@ -232,9 +267,10 @@
     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.
+    RetainPtr<UIDocumentMenuViewController> _documentMenuController;
+    RetainPtr<UIAlertController> _actionSheetController;
 }
 
 - (instancetype)initWithView:(WKContentView *)view
@@ -249,6 +285,8 @@
 {
     [_imagePicker setDelegate:nil];
     [_presentationPopover setDelegate:nil];
+    [_documentMenuController setDelegate:nil];
+
     [super dealloc];
 }
 
@@ -305,6 +343,13 @@
         [mimeTypes addObject:mimeType->string()];
     _mimeTypes = adoptNS([mimeTypes copy]);
 
+    // FIXME: Remove this check and the fallback code when a new SDK is available. <rdar://problem/20150072>
+    if ([UIDocumentMenuViewController instancesRespondToSelector:@selector(_setIgnoreApplicationEntitlementForImport:)]) {
+        [self _showDocumentPickerMenu];
+        return;
+    }
+
+    // Fall back to showing the old-style source selection sheet.
     // 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])
@@ -334,7 +379,7 @@
     }
 }
 
-#pragma mark - Action Sheet
+#pragma mark - Media Types
 
 static bool stringHasPrefixCaseInsensitive(NSString *str, NSString *prefix)
 {
@@ -342,45 +387,76 @@
     return range.location != NSNotFound;
 }
 
-- (NSArray *)_mediaTypesForPickerSourceType:(UIImagePickerControllerSourceType)sourceType
+static NSArray *UTIsForMIMETypes(NSArray *mimeTypes)
 {
     // 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()) {
+    for (NSString *mimeType in mimeTypes) {
+        // FIXME: We should support more MIME type -> UTI mappings. <http://webkit.org/b/142614>
         if (stringHasPrefixCaseInsensitive(mimeType, @"image/"))
             [mediaTypes addObject:(NSString *)kUTTypeImage];
         else if (stringHasPrefixCaseInsensitive(mimeType, @"video/"))
             [mediaTypes addObject:(NSString *)kUTTypeMovie];
     }
 
-    if ([mediaTypes count])
-        return [mediaTypes allObjects];
+    return mediaTypes.allObjects;
+}
 
+- (NSArray *)_mediaTypesForPickerSourceType:(UIImagePickerControllerSourceType)sourceType
+{
+    NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get());
+    if (mediaTypes.count)
+        return mediaTypes;
+
     // Fallback to every supported media type if there is no filter.
     return [UIImagePickerController availableMediaTypesForSourceType:sourceType];
 }
 
-- (void)_showMediaSourceSelectionSheet
+- (NSArray *)_documentPickerMenuMediaTypes
 {
-    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");
+    NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get());
+    if (mediaTypes.count)
+        return mediaTypes;
 
+    // Fallback to every supported media type if there is no filter.
+    return @[@"public.item"];
+}
+
+#pragma mark - Source selection menu
+
+- (NSString *)_photoLibraryButtonLabel
+{
+    return 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 *)_cameraButtonLabel
+{
+    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
+        return nil;
+
     // 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");
+        return 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");
 
+    if (containsVideoMediaType)
+        return WEB_UI_STRING_KEY("Take Video", "Take Video (file upload action sheet)", "File Upload alert sheet camera button string for taking only videos");
+
+    return WEB_UI_STRING_KEY("Take Photo", "Take Photo (file upload action sheet)", "File Upload alert sheet camera button string for taking only photos");
+}
+
+- (void)_showMediaSourceSelectionSheet
+{
+    NSString *existingString = [self _photoLibraryButtonLabel];
+    NSString *cameraString = [self _cameraButtonLabel];
+    NSString *cancelString = WEB_UI_STRING_KEY("Cancel", "Cancel (file upload action sheet)", "File Upload alert sheet button string to cancel");
+
     _actionSheetController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
 
     UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelString style:UIAlertActionStyleCancel handler:^(UIAlertAction *){
@@ -402,12 +478,34 @@
     [_actionSheetController addAction:cameraAction];
     [_actionSheetController addAction:photoLibraryAction];
 
-    if (UICurrentUserInterfaceIdiomIsPad())
-        [self _presentPopoverWithContentViewController:_actionSheetController.get() animated:YES];
-    else
-        [self _presentFullscreenViewController:_actionSheetController.get() animated:YES];
+    [self _presentForCurrentInterfaceIdiom:_actionSheetController.get()];
 }
 
+- (void)_showDocumentPickerMenu
+{
+    // FIXME: Support multiple file selection when implemented. <rdar://17177981>
+    // FIXME: We call -_setIgnoreApplicationEntitlementForImport: before initialization, because the assertion we're trying
+    // to suppress is in the initializer. <rdar://problem/20137692> tracks doing this with a private initializer.
+    _documentMenuController = adoptNS([UIDocumentMenuViewController alloc]);
+    [_documentMenuController _setIgnoreApplicationEntitlementForImport:YES];
+    [_documentMenuController initWithDocumentTypes:[self _documentPickerMenuMediaTypes] inMode:UIDocumentPickerModeImport];
+    [_documentMenuController setDelegate:self];
+
+    // FIXME: Need icons for Camera and Photo Library options.
+    [_documentMenuController addOptionWithTitle:[self _photoLibraryButtonLabel] image:nil order:UIDocumentMenuOrderFirst handler:^{
+        [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
+    }];
+
+    if (NSString *cameraString = [self _cameraButtonLabel]) {
+        [_documentMenuController addOptionWithTitle:cameraString image:nil order:UIDocumentMenuOrderFirst handler:^{
+            _usingCamera = YES;
+            [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypeCamera];
+        }];
+    }
+
+    [self _presentForCurrentInterfaceIdiom:_documentMenuController.get()];
+}
+
 #pragma mark - Image Picker
 
 - (void)_showPhotoPickerWithSourceType:(UIImagePickerControllerSourceType)sourceType
@@ -431,6 +529,14 @@
 
 #pragma mark - Presenting View Controllers
 
+- (void)_presentForCurrentInterfaceIdiom:(UIViewController *)viewController
+{
+    if (UICurrentUserInterfaceIdiomIsPad())
+        [self _presentPopoverWithContentViewController:viewController animated:YES];
+    else
+        [self _presentFullscreenViewController:viewController animated:YES];
+}
+
 - (void)_presentPopoverWithContentViewController:(UIViewController *)contentViewController animated:(BOOL)animated
 {
     [self _dismissDisplayAnimated:animated];
@@ -455,6 +561,36 @@
     [self _cancel];
 }
 
+#pragma mark - UIDocumentMenuDelegate implementation
+
+- (void)documentMenu:(UIDocumentMenuViewController *)documentMenu didPickDocumentPicker:(UIDocumentPickerViewController *)documentPicker
+{
+    documentPicker.delegate = self;
+    documentPicker.modalPresentationStyle = UIModalPresentationFullScreen;
+
+    [self _presentForCurrentInterfaceIdiom:documentPicker];
+}
+
+- (void)documentMenuWasCancelled:(UIDocumentMenuViewController *)documentMenu
+{
+    [self _dismissDisplayAnimated:YES];
+    [self _cancel];
+}
+
+#pragma mark - UIDocumentPickerControllerDelegate implementation
+
+- (void)documentPicker:(UIDocumentPickerViewController *)documentPicker didPickDocumentAtURL:(NSURL *)url
+{
+    [self _dismissDisplayAnimated:YES];
+    [self _chooseFiles:@[url] displayString:url.lastPathComponent iconImage:iconForFile(url)];
+}
+
+- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)documentPicker
+{
+    [self _dismissDisplayAnimated:YES];
+    [self _cancel];
+}
+
 #pragma mark - UIImagePickerControllerDelegate implementation
 
 - (BOOL)_willMultipleSelectionDelegateBeCalled
@@ -574,8 +710,7 @@
             return;
         }
 
-        NSString *filePath = [mediaURL path];
-        successBlock(adoptNS([[_WKVideoFileUploadItem alloc] initWithFilePath:filePath mediaURL:mediaURL]).get());
+        successBlock(adoptNS([[_WKVideoFileUploadItem alloc] initWithFileURL:mediaURL]).get());
         return;
     }
 
@@ -627,7 +762,7 @@
                 return;
             }
 
-            successBlock(adoptNS([[_WKImageFileUploadItem alloc] initWithFilePath:filePath originalImage:originalImage]).get());
+            successBlock(adoptNS([[_WKImageFileUploadItem alloc] initWithFileURL:[NSURL fileURLWithPath:filePath] originalImage:originalImage]).get());
         });
         return;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to