Modified: trunk/Source/WebCore/ChangeLog (242368 => 242369)
--- trunk/Source/WebCore/ChangeLog 2019-03-04 19:58:34 UTC (rev 242368)
+++ trunk/Source/WebCore/ChangeLog 2019-03-04 20:20:59 UTC (rev 242369)
@@ -1,3 +1,15 @@
+2019-03-04 Chris Dumez <[email protected]>
+
+ [iOS] Improve our file picker
+ https://bugs.webkit.org/show_bug.cgi?id=195284
+ <rdar://problem/45655856>
+
+ Reviewed by Tim Horton and Wenson Hsieh.
+
+ Export UTIUtilities.h so that it can be used from WebKit2.
+
+ * WebCore.xcodeproj/project.pbxproj:
+
2019-03-04 Zalan Bujtas <[email protected]>
[ContentChangeObserver] Decouple mouseMoved event and the "is observing content change" status.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (242368 => 242369)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-03-04 19:58:34 UTC (rev 242368)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-03-04 20:20:59 UTC (rev 242369)
@@ -660,7 +660,7 @@
1F3C3BEB135CAF3C00B8C1AC /* MediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3C3BE9135CAF3C00B8C1AC /* MediaControls.h */; };
1F72BF0B187FD45C0009BCB3 /* TileControllerMemoryHandlerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
1F8756B21E22C3350042C40D /* WebSQLiteDatabaseTrackerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F8756B11E22BEEF0042C40D /* WebSQLiteDatabaseTrackerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 1FAFBF1915A5FA7400083A20 /* UTIUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FAFBF1615A5FA5200083A20 /* UTIUtilities.h */; };
+ 1FAFBF1915A5FA7400083A20 /* UTIUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FAFBF1615A5FA5200083A20 /* UTIUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
1FC40FBA1655CCB90040F29E /* SubimageCacheWithTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FC40FB71655C5910040F29E /* SubimageCacheWithTimer.h */; };
20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 20D629251253690B00081543 /* InspectorInstrumentation.h */; };
225A16B50D5C11E900090295 /* WebEventRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 225A16B30D5C11E900090295 /* WebEventRegion.h */; settings = {ATTRIBUTES = (Private, ); }; };
Modified: trunk/Source/WebCore/platform/network/mac/UTIUtilities.h (242368 => 242369)
--- trunk/Source/WebCore/platform/network/mac/UTIUtilities.h 2019-03-04 19:58:34 UTC (rev 242368)
+++ trunk/Source/WebCore/platform/network/mac/UTIUtilities.h 2019-03-04 20:20:59 UTC (rev 242369)
@@ -32,7 +32,7 @@
namespace WebCore {
String MIMETypeFromUTI(const String&);
String MIMETypeFromUTITree(const String&);
-String UTIFromMIMEType(const String&);
+WEBCORE_EXPORT String UTIFromMIMEType(const String&);
bool isDeclaredUTI(const String&);
}
Modified: trunk/Source/WebKit/ChangeLog (242368 => 242369)
--- trunk/Source/WebKit/ChangeLog 2019-03-04 19:58:34 UTC (rev 242368)
+++ trunk/Source/WebKit/ChangeLog 2019-03-04 20:20:59 UTC (rev 242369)
@@ -1,3 +1,35 @@
+2019-03-04 Chris Dumez <[email protected]>
+
+ [iOS] Improve our file picker
+ https://bugs.webkit.org/show_bug.cgi?id=195284
+ <rdar://problem/45655856>
+
+ Reviewed by Tim Horton and Wenson Hsieh.
+
+ Improve our file picker on iOS so that:
+ - Accepted file extensions specified in the HTML (e.g. <input type="file"> accept=".pdf">) are now
+ properly reflected in the file picker. Previously, we only we only supported MIME types in the
+ accept attribute that only Image / Video ones.
+ - If accepted types are specified in the HTML and not of them are Video or Image types, then bypass
+ the UIDocumentMenuViewController and show the file picker directly (as if the user had tapped on
+ "Browse..." on that menu). Other menu items such as "Take Photo or Video" and "Photo Library" do
+ not make sense if the page only accepts PDF files for example.
+
+ Things that we should do but are not fixed in this patch:
+ - Stop using UIDocumentMenuViewController entirely since it was deprecated in favor of using
+ UIDocumentPickerViewController directly.
+ - Add multiple selection support, which is supported both on the HTML side and in the
+ UIDocumentPickerViewController API.
+
+ * UIProcess/ios/forms/WKFileUploadPanel.mm:
+ (arrayContainsUTIThatConformsTo):
+ (-[WKFileUploadPanel dealloc]):
+ (-[WKFileUploadPanel presentWithParameters:resultListener:]):
+ (UTIsForMIMETypes):
+ (-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
+ (-[WKFileUploadPanel _cameraButtonLabelAllowingPhoto:allowingVideo:]):
+ (-[WKFileUploadPanel _showDocumentPickerMenu]):
+
2019-03-04 Alex Christensen <[email protected]>
REGRESSION: ( r240978-r240985 ) [ iOS Release ] Layout Test imported/w3c/web-platform-tests/xhr/send-redirect-post-upload.htm is crashing
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm (242368 => 242369)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm 2019-03-04 19:58:34 UTC (rev 242368)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm 2019-03-04 20:20:59 UTC (rev 242369)
@@ -41,8 +41,12 @@
#import "WebOpenPanelResultListenerProxy.h"
#import "WebPageProxy.h"
#import <MobileCoreServices/MobileCoreServices.h>
+#import <UIKit/UIDocumentPickerViewController.h>
#import <WebCore/LocalizedStrings.h>
+#import <WebCore/MIMETypeRegistry.h>
+#import <WebCore/UTIUtilities.h>
#import <wtf/RetainPtr.h>
+#import <wtf/text/StringView.h>
using namespace WebKit;
@@ -53,6 +57,15 @@
return mediaCaptureType == WebCore::MediaCaptureTypeUser ? UIImagePickerControllerCameraDeviceFront : UIImagePickerControllerCameraDeviceRear;
}
+static bool arrayContainsUTIThatConformsTo(NSArray<NSString *> *typeIdentifiers, CFStringRef conformToUTI)
+{
+ for (NSString *uti in typeIdentifiers) {
+ if (UTTypeConformsTo((__bridge CFStringRef)uti, conformToUTI))
+ return true;
+ }
+ return false;
+}
+
#pragma mark - Document picker icons
static inline UIImage *photoLibraryIcon()
@@ -163,6 +176,7 @@
RetainPtr<UIPopoverController> _presentationPopover; // iPad for action sheet and Photo Library.
ALLOW_DEPRECATED_DECLARATIONS_END
RetainPtr<UIDocumentMenuViewController> _documentMenuController;
+ RetainPtr<UIDocumentPickerViewController> _documentPickerController;
WebCore::MediaCaptureType _mediaCaptureType;
}
@@ -179,6 +193,7 @@
[_imagePicker setDelegate:nil];
[_presentationPopover setDelegate:nil];
[_documentMenuController setDelegate:nil];
+ [_documentPickerController setDelegate:nil];
[super dealloc];
}
@@ -233,6 +248,14 @@
NSMutableArray *mimeTypes = [NSMutableArray arrayWithCapacity:acceptMimeTypes->size()];
for (auto mimeType : acceptMimeTypes->elementsOfType<API::String>())
[mimeTypes addObject:mimeType->string()];
+
+ Ref<API::Array> acceptFileExtensions = parameters->acceptFileExtensions();
+ for (auto extension : acceptFileExtensions->elementsOfType<API::String>()) {
+ String mimeType = WebCore::MIMETypeRegistry::getMIMETypeForExtension(extension->stringView().substring(1).toString());
+ if (!mimeType.isEmpty())
+ [mimeTypes addObject:mimeType];
+ }
+
_mimeTypes = adoptNS([mimeTypes copy]);
_mediaCaptureType = WebCore::MediaCaptureTypeNone;
@@ -291,27 +314,14 @@
#pragma mark - Media Types
-static bool stringHasPrefixCaseInsensitive(NSString *str, NSString *prefix)
-{
- NSRange range = [str rangeOfString:prefix options:(NSCaseInsensitiveSearch | NSAnchoredSearch)];
- return range.location != NSNotFound;
-}
-
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) {
- // 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];
+ auto uti = WebCore::UTIFromMIMEType(mimeType);
+ if (!uti.isEmpty())
+ [mediaTypes addObject:(__bridge NSString *)uti];
}
-
return mediaTypes.allObjects;
}
@@ -325,16 +335,6 @@
return [UIImagePickerController availableMediaTypesForSourceType:sourceType];
}
-- (NSArray *)_documentPickerMenuMediaTypes
-{
- 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
@@ -342,20 +342,13 @@
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
+- (NSString *)_cameraButtonLabelAllowingPhoto:(BOOL)allowPhoto allowingVideo:(BOOL)allowVideo
{
- if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
- return nil;
-
- // Choose the appropriate string for the camera button.
- NSArray *filteredMediaTypes = [self _mediaTypesForPickerSourceType:UIImagePickerControllerSourceTypeCamera];
- BOOL containsImageMediaType = [filteredMediaTypes containsObject:(NSString *)kUTTypeImage];
- BOOL containsVideoMediaType = [filteredMediaTypes containsObject:(NSString *)kUTTypeMovie];
- ASSERT(containsImageMediaType || containsVideoMediaType);
- if (containsImageMediaType && containsVideoMediaType)
+ ASSERT(allowPhoto || allowVideo);
+ if (allowPhoto && allowVideo)
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)
+ if (allowVideo)
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");
@@ -363,25 +356,40 @@
- (void)_showDocumentPickerMenu
{
- // FIXME: Support multiple file selection when implemented. <rdar://17177981>
- _documentMenuController = adoptNS([[UIDocumentMenuViewController alloc] _initIgnoringApplicationEntitlementForImportOfTypes:[self _documentPickerMenuMediaTypes]]);
- [_documentMenuController setDelegate:self];
+ NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get());
- [_documentMenuController addOptionWithTitle:[self _photoLibraryButtonLabel] image:photoLibraryIcon() order:UIDocumentMenuOrderFirst handler:^{
- [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
- }];
+ BOOL containsImageMediaType = !mediaTypes.count || arrayContainsUTIThatConformsTo(mediaTypes, kUTTypeImage);
+ BOOL containsVideoMediaType = !mediaTypes.count || arrayContainsUTIThatConformsTo(mediaTypes, kUTTypeMovie);
- if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
- if (NSString *cameraString = [self _cameraButtonLabel]) {
+ NSArray *documentTypes = mediaTypes.count ? mediaTypes : @[(__bridge NSString *)kUTTypeItem];
+ if (containsImageMediaType || containsVideoMediaType) {
+ // FIXME: UIDocumentMenuViewController is deprecated, we should use UIDocumentPickerViewController instead.
+ // FIXME: Support multiple file selection when implemented. <rdar://17177981>
+ _documentMenuController = adoptNS([[UIDocumentMenuViewController alloc] _initIgnoringApplicationEntitlementForImportOfTypes:documentTypes]);
+ [_documentMenuController setDelegate:self];
+
+ [_documentMenuController addOptionWithTitle:[self _photoLibraryButtonLabel] image:photoLibraryIcon() order:UIDocumentMenuOrderFirst handler:^{
+ [self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
+ }];
+
+ if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
+ NSString *cameraString = [self _cameraButtonLabelAllowingPhoto:containsImageMediaType allowingVideo:containsVideoMediaType];
[_documentMenuController addOptionWithTitle:cameraString image:cameraIcon() order:UIDocumentMenuOrderFirst handler:^{
_usingCamera = YES;
[self _showPhotoPickerWithSourceType:UIImagePickerControllerSourceTypeCamera];
}];
}
+
+ [self _presentMenuOptionForCurrentInterfaceIdiom:_documentMenuController.get()];
+ } else {
+ // Image and Video types are not accepted so bypass the menu and open the file picker directly.
+ // FIXME: Support multiple file selection when implemented. <rdar://17177981>
+ _documentPickerController = adoptNS([[UIDocumentPickerViewController alloc] initWithDocumentTypes:documentTypes inMode:UIDocumentPickerModeImport]);
+ [_documentPickerController setDelegate:self];
+ [self _presentFullscreenViewController:_documentPickerController.get() animated:YES];
}
- [self _presentMenuOptionForCurrentInterfaceIdiom:_documentMenuController.get()];
- // Clear out the view controller we just presented. Don't save a reference to the UIDocumentMenuViewController as it is self dismissing.
+ // Clear out the view controller we just presented. Don't save a reference to the UIDocumentMenuViewController / UIDocumentPickerViewController as it is self dismissing.
_presentationViewController = nil;
}