[webkit-reviews] review granted: [Bug 212485] [macOS]: The File Picker of the <input> file element should show the selection filter : [Attachment 401407] Patch
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Wed Jun 10 11:54:37 PDT 2020
Darin Adler <darin at apple.com> has granted Said Abou-Hallawa
<sabouhallawa at apple.com>'s request for review:
Bug 212485: [macOS]: The File Picker of the <input> file element should show
the selection filter
https://bugs.webkit.org/show_bug.cgi?id=212485
Attachment 401407: Patch
https://bugs.webkit.org/attachment.cgi?id=401407&action=review
--- Comment #20 from Darin Adler <darin at apple.com> ---
Comment on attachment 401407
--> https://bugs.webkit.org/attachment.cgi?id=401407
Patch
View in context: https://bugs.webkit.org/attachment.cgi?id=401407&action=review
Looks OK. Where are the tests for this new code?
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:37
> + static NeverDestroyed<RetainPtr<NSDictionary<NSString *, NSSet<NSString
*> *>>> s_mimeTypeToExtensions;
> + static dispatch_once_t onceToken;
Do we need a thread-safe one-time mechanism here? If so, why choose
dispatch_once of std::call_once? If not, can we just write this with normal C++
initialization idioms?
static NSDictionary<NSString *, NSSet<NSString *> *map =
createMIMETypeToExtensionsMap().leakRef();
Or use a block if you prefer.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:40
> + NSMutableDictionary<NSString *, NSMutableSet<NSString *> *>
*mimeTypeToExtensions = [NSMutableDictionary dictionary];
I suggest avoiding autorelease here:
auto mimeTypeToExtensions = adoptNS([[NSMutableDictionary alloc] init]);
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:41
> + RetainPtr<NSArray> allUTIs =
adoptCF(_UTCopyDeclaredTypeIdentifiers());
I suggest using auto for code like this. Also I am surprised we can just assign
from a RetainPtr<CFArrayRef> into a RetainPtr<NSArray> without a cast. Does
this really compile?
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:43
> + void (^addExtensionForMIMEType)(NSString *mimeType, NSString
*extension) = ^(NSString *mimeType, NSString *extension) {
And here.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:45
> + mimeTypeToExtensions[mimeType] = [NSMutableSet set];
It’s a little bit unfortunate to autorelease the set here. Could write this so
autorelease is not involved:
mimeTypeToExtensions[mimeType] = adoptNS([[NSMutableSet alloc]
init]).get();
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:49
> + void (^addExtensionsForMIMEType)(NSString *mimeType,
NSArray<NSString *> *extensions) = ^(NSString *mimeType, NSArray<NSString *>
*extensions) {
And here.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:61
> + RetainPtr<NSString> mimeType =
adoptCF(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)(uti),
kUTTagClassMIMEType));
And here.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:64
> + RetainPtr<NSArray> extensions =
adoptCF(UTTypeCopyAllTagsWithClass((__bridge CFStringRef)(uti),
kUTTagClassFilenameExtension));
And here.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:75
> + RetainPtr<NSDictionary<NSString *, NSArray<NSString *> *>>
whitelistedMimeTypes = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:
> + [NSArray arrayWithObjects: @"webp" , nil], @"image/webp",
> + nil
> + ]);
> +
> + [whitelistedMimeTypes.get()
enumerateKeysAndObjectsUsingBlock:^(NSString *mimeType, NSArray<NSString *>
*extensions, BOOL *) {
> + addExtensionsForMIMEType(mimeType, extensions);
> + }];
And here. Also I suggest not using the term "whitelist". Also using literals
makes this way nicer:
auto allowedMIMETypes = @{ @"image/webp": @[ @"webp" ] };
When it’s written this way, it becomes pretty clear that "allowedMIMETypes" is
a strange name for this dictionary, and also that it’s strange to use a
dictionary. Why do we need to make a dictionary and enumerate it? Why not just
write this one line of code:
addExtensionForMIMEType(@"image/webp", @"webp");
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:120
> + NSArray<NSString *> *acceptedMIMETypes = [self _acceptedMIMETypes];
> + NSArray<NSString *> *acceptedFileExtensions = [self
_acceptedFileExtensions];
I suggest auto here.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:122
> + NSMutableSet<NSString *> *allowedFileExtensions = [NSMutableSet set];
I suggest auto and adoptNS here to avoid autorelease.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:129
> + NSMutableArray<NSString *> *additionalAllowedFileExtensions =
[NSMutableArray array];
I suggest auto and adoptNS here to avoid autorelease.
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:142
> + NSArray<NSString *> *acceptedMIMETypes = [self _acceptedMIMETypes];
> + NSArray<NSString *> *acceptedFileExtensions = [self
_acceptedFileExtensions];
auto
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:148
> + return @"Custom Files";
Maybe a named constant for this string. Is it OK that this is not localized?
> Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm:160
> + return [NSString stringWithFormat:@"%@%@ Files", [[mimeTypePrefix
substringToIndex:1] uppercaseString], [mimeTypePrefix substringFromIndex:1]];
Is it OK that this is not localized?
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:78
> + NSOpenPanel *_openPanel;
What guarantees this object will not be retained and outlive the open panel?
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:79
> + NSArray<NSString *> *_allowedFileExtensions;
Why not use RetainPtr for this?
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:124
> + FileExtensionsPopupTarget *_fileExtensionsPopupTarget;
Why not use RetainPtr for this?
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:630
> + NSTextField* label = [[[NSTextField alloc] initWithFrame:NSZeroRect]
autorelease];
I suggest using adoptNS instead of autorelease.
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:638
> + NSPopUpButton *button = [[[NSPopUpButton alloc] initWithFrame:NSZeroRect
pullsDown:NO] autorelease];
Ditto.
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:646
> + NSView* filterView = [[[NSView alloc] initWithFrame:NSZeroRect]
autorelease];
Ditto.
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:652
> + const CGFloat margin = 20;
> + const CGFloat spacing = 2;
> + const CGFloat minButtonWidth = 230;
constexpr is better than const for this use.
Also would be helpful to have a comment saying where these values come from.
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:659
> + buttonFrame.size = NSMakeSize(MAX(NSWidth(buttonFrame), minButtonWidth),
NSHeight(buttonFrame));
Could use std::max instead of MAX.
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:670
> + buttonFrame.origin = NSMakePoint(NSMaxX(labelFrame) + 2,
(NSHeight(filterViewFrame) - NSHeight(buttonFrame)) / 2);
Where does the magic number in the "+ 2" come from? Why is it correct?
>> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:693
>> + titles = @[@"All Files"];
>
> I removed the extra spaces, which I used as a hack to increase the width of
the NSPopupButton, and I fixed the layout of the controls.
Is it OK that the string "All Files" is not localized? If so, why?
> Tools/MiniBrowser/mac/WK2BrowserWindowController.m:695
> + NSView *filterView = [self createFilterView:titles
popupTarget:_fileExtensionsPopupTarget];
This method name has "create" in it. Does that mean we need to adopt or release
its return value? Or does it just happen to have a name that violates the Cocoa
copy/create ownership rule?
More information about the webkit-reviews
mailing list