[Webkit-unassigned] [Bug 137759] [Mac] Add API for open panel handling to WKWebView
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Sun Jan 24 20:12:24 PST 2016
https://bugs.webkit.org/show_bug.cgi?id=137759
--- Comment #44 from Brian Michel <brian.michel at gmail.com> ---
(In reply to comment #42)
> Comment on attachment 269672 [details]
> Patch
>
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=269672&action=review
>
> Looks like good work. Thanks for tackling this!
>
> I have many small comments, some are important, others are less important
> details but still worth improving.
>
> review- mainly because of the most serious problem, the lifetime mistake in
> WKConcreteOpenPanelResultListener where it doesnât ref/deref the underlying
> listener proxy C++ object.
>
> > Source/WebKit2/ChangeLog:3
> > + Handle Open Panel Functions Are Unimplemented
>
> We donât capitalize every word of bug titles; even though they are âtitlesâ,
> âtitle caseâ is not called for.
>
> > Source/WebKit2/ChangeLog:23
> > + * Shared/API/Cocoa/WebKit.h:
> > + * UIProcess/API/Cocoa/WKUIDelegate.h:
> > + * UIProcess/API/Cocoa/WKUIOpenPanelParameters.h: Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h.
> > + * UIProcess/API/Cocoa/WKUIOpenPanelParameters.m: Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h.
> > + (-[WKUIOpenPanelParameters _setAllowsMultipleFiles:]):
> > + * UIProcess/API/Cocoa/WKUIOpenPanelParametersPrivate.h: Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h.
> > + * UIProcess/Cocoa/UIDelegate.h:
> > + * UIProcess/Cocoa/UIDelegate.mm:
> > + (WebKit::UIDelegate::setDelegate):
> > + (WebKit::UIDelegate::UIClient::runOpenPanel):
> > + * UIProcess/Cocoa/WKConcreteOpenPanelResultListener.h: Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h.
> > + * UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m: Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h.
> > + (-[WKConcreteOpenPanelResultListener initWithListenerProxy:]):
> > + (-[WKConcreteOpenPanelResultListener chooseFiles:]):
> > + (-[WKConcreteOpenPanelResultListener cancel]):
> > + * WebKit2.xcodeproj/project.pbxproj:
>
> A good quality change log should have comments about what each change was,
> and should only list function names when there is a change in the function.
>
> All those "Copied from Source/WebKit2/Shared/API/Cocoa/WebKit.h" also look
> incorrect. The script generated incorrect stuff there, and you need to
> replace those mistakes with a useful change log entry.
>
> > Source/WebKit2/ChangeLog:108
> > - (because createWebPage, which usually brings it up, hasn't happened yet), and we
> > + (because createWebPage, which usually brings it up, hasn't happened yet), and we
>
> Trimming all the trailing whitespace from the ChangeLog is not typically
> something we want to do; makes the patch bigger for no good reason.
>
> I suppose we could add a pre-commit hook to prevent people from landing such
> whitespace in the first place to avoid this in the future.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:39
> > + at class WKWebView;
> > + at class WKUIOpenPanelParameters;
>
> We normally keep these alphabetically, so please sort these in instead of
> adding them at the bottom.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:43
> > +/*! A class conforming to WKOpenPanelResultListener provides methods
> > +for interacting with files.
> > +*/
>
> This seems a bit vague and oblique. I looked at Apple documentation to see
> how they write these and it would be something more like:
>
> /*! The WKOpenPanelResultListener protocol defines the methods that a file
> open panel implementation must invokes when the open interaction is complete.
> */
>
> One critical question is whether we have a threading rule about this class
> or not. I think we would want these methods to be callable on any thread.
> And we also want it to be safe to deallocate this object on any thread.
> Thatâs tricky to get right.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:46
> > +/*! @abstract passes an array of file urls to the web view.
>
> Should be capitalized: âPassesâ.
>
> âfile URLsâ, not âfile urlsâ.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:47
> > + @param fileURLs The array of file urls to pass to the web view.
>
> Ditto.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:48
> > + @discussion passing nil, or an empty array will have the effect of calling the cancel selector.
>
> There should not be a comma after the word "nil".
>
> But more importantly in a new API we should not be talking about passing
> nil, since we are not marking this as a nullable argument. Callers should
> pass @[] rather than nil.
>
> I also donât think the wording âwill have the effect of calling the cancel
> selectorâ is quite right. I would write something a little more like this:
>
> @discussion Passing an empty array cancels the file open interaction as the
> cancel method does.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:50
> > +- (void)chooseFiles:(NSArray *)fileURLs;
>
> The type here should be NSArray<NSURL *> *, which will make things nicer
> both for programmers using Objective-C and Swift. Not sure exactly how we
> are handling using that feature in WebKit API at this time; there may be
> some compatibility issue for older versions of clang. If nobody else knows,
> Anders at least should know.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:139
> > + @param listener The listener object to be called when selection has completed
> > + or cancelled.
>
> Iâd put this all on one line. No need to wrap this. Even though some of the
> comments above are wrapped like this.
>
> Wording not quite right here. I donât think we would say that "selection has
> completed". We donât "call" an object, we invoke one of its methods. And a
> selection doesnât complete nor does it cancel. So I think better wording
> would be more like:
>
> The listener object with methods to be invoked when the user makes a
> selection or cancels.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegate.h:140
> > + @param parameters Parameters to configure the open panel with as specificed by the webpage.
>
> typo: "specificed"
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIOpenPanelParameters.h:32
> > +/*! A class to pass configuration flags to an open panel based on options specified in the webpage.
>
> Comment should be more like the ones on other classes in this directory.
> Hereâs a rough cut:
>
> A WKUIOpenPanelParameters object is a collection of options specified in
> a webpage to customize an open panel.
>
> My wording isnât quite right either, though.
>
> Not sure that âparametersâ is the right name for this class. There arenât
> any other WebKit classes that use the name parameters like this. I looked
> for other similar ones.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIOpenPanelParameters.h:37
> > +/*! @abstract Whether or not multiple files are allowed.
> > + */
>
> Looking at other comments, it seems this one should be more like this:
>
> /*! @abstract A Boolean value indicating whether or not the open panel
> should allow selection of more than one file.
> */
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIOpenPanelParameters.m:33
> > +- (void)_setAllowsMultipleFiles:(BOOL)allowsMultipleFiles {
>
> WebKit coding style puts the brace on a separate line.
>
> > Source/WebKit2/UIProcess/API/Cocoa/WKUIOpenPanelParametersPrivate.h:30
> > + at interface WKUIOpenPanelParameters (WKPrivate)
>
> This should be Internal, not Private. Both the category name and the file
> name. Things marked Internal are for use only within the WebKit2 framework.
> Things marked Private are SPI, so can be used outside the framework. This is
> Internal.
>
> > Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm:104
> > +#if PLATFORM(MAC)
> > + m_delegateMethods.webViewRunOpenPanelWithResultListenerParameters = [delegate respondsToSelector:@selector(webView:runOpenPanelWithResultListener:parameters:)];
> > +#endif
>
> Would be nice to put the conditional ones after the unconditional ones. I
> see that PLATFORM(IOS) ones are above, but I suggest putting this down at
> the bottom, after the ENABLE(CONTEXT_MENUS) ones.
>
> > Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm:241
> > +bool UIDelegate::UIClient::runOpenPanel(WebKit::WebPageProxy *page, WebKit::WebFrameProxy *frame, WebKit::WebOpenPanelParameters *parameters, WebKit::WebOpenPanelResultListenerProxy *listener)
>
> Formatting here is wrong for WebKit coding style (should be "WebPageProxy*"
> with the * next to the type name), and the explicit WebKit prefixes are not
> needed.
>
> > Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm:247
> > + // If our delegate does not support this method, invalidate the listener and return false.
> > + if (!m_uiDelegate.m_delegateMethods.webViewRunOpenPanelWithResultListenerParameters) {
> > + listener->invalidate();
> > + return false;
> > + }
>
> In WebKit code we try to avoid writing comments that say the same thing the
> code does. This is an example of that anti-pattern, so please omit the
> comment.
>
> You should write a comment when you need to explain *why* the code does what
> it does.
>
> > Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm:254
> > + NSWindow *window = [m_uiDelegate.m_webView window];
> > +
> > + if (!window) {
> > + listener->invalidate();
> > + return false;
> > + }
>
> I donât understand why this code is here. Whether to do this without a
> window seems like a decision for the delegate, not to be decided by WebKit.
> Please donât enforce a "no window, no call to delegate" policy here, unless
> there is a compelling reason to do so.
>
> > Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm:261
> > + [delegate webView:m_uiDelegate.m_webView runOpenPanelWithResultListener:(id <WKOpenPanelResultListener>)adoptNS([[WKConcreteOpenPanelResultListener alloc] initWithListenerProxy:listener]) parameters:(WKUIOpenPanelParameters *)delegateParameters];
>
> This should be using "adoptNS([[WKConcreteOpenPanelResultListener alloc]
> initWithListenerProxy:listener]).get()" rather than "(id
> <WKOpenPanelResultListener>)adoptNS([[WKConcreteOpenPanelResultListener
> alloc] initWithListenerProxy:listener])". Might also want to use a local
> variable so this line isnât so super-long.
>
> This should be using "delegateParameters.get()" rather than
> "(WKUIOpenPanelParameters *)delegateParameters".
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.h:2
> > + * Copyright (C) 2015 Brian Michel (brian.michel at gmail.com). All rights reserved.
>
> 2016
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.h:37
> > +- (instancetype)initWithListenerProxy:(WebKit::WebOpenPanelResultListenerProxy *)proxy;
>
> In WebKit coding style there should not be a space before "*" on this line.
>
> I suggest naming this method initWithProxy: rather than
> initWithListenerProxy: because since this object is a listener, it stands to
> reason the proxy would be a listener proxy.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:41
> > + WebOpenPanelResultListenerProxy *m_listener;
>
> This object needs to ref the listener. Otherwise, this listener can outlive
> the proxy. However, using RefPtr for this would be dangerous because it will
> make the dealloc method call deref on whatever thread the object is released
> on. Instead we probably want to use callOnMainThread in the dealloc method
> to make sure the deref happens on the main thread.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:44
> > +- (instancetype)initWithListenerProxy:(WebOpenPanelResultListenerProxy *)proxy {
>
> WebKit coding style puts the open brace on a separate line.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:53
> > +#pragma mark - WKOpenPanelResultListener
>
> Not sure we really need this mark. This is a small simple class.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:55
> > +- (void)chooseFiles:(NSArray *)fileURLs {
>
> To make it safe to call this on any thread, I think we need to use
> callOnMainThread in this method and put the actual work inside the block or
> lambda that we call on the main thread. We also need to capture self (and
> retain it here and release it in the block or lambda).
>
> Also would be nice to make it safe to call this method multiple times. I
> think the way to do that would be to null out m_listener after this is
> called the first time, and then make sure itâs a no-op if m_listener is
> already null. As with the work I mentioned above and the deref in the
> dealloc function, the work has to be done on the main thread.
>
> WebKit coding style puts the open brace on a separate line.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:57
> > + NSUInteger count = [fileURLs count];
> > + if (!count)
>
> No reason to put this into a local variable since we only use it once. Iâd
> write this:
>
> if (!fileURLs.count)
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:60
> > + Vector<RefPtr<API::Object>> urls;
>
> I personally would dodge the ugly "urls" name by naming the vector something
> else, like "files".
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:64
> > + for (NSURL *fileURL in fileURLs)
> > + urls.uncheckedAppend(adoptRef(toImpl(WKURLCreateWithCFURL((CFURLRef)fileURL))));
>
> We should consider throwing an Objective-C exception if any of the elements
> in the array are not NSURL objects. That would make it easier for
> programmers to figure out what they did wrong than the crash they might
> otherwise see. Maybe not, though. Doesnât seem like other WebKit API code is
> taking this approach, so I guess itâs OK to leave as is for now.
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:67
> > + RefPtr<API::Array> fileURLsRef = API::Array::create(std::move(urls));
> > + m_listener->chooseFiles(fileURLsRef.get());
>
> No need for the local variable. In WebKit code, should use WTFMove instead
> of std::move, so should be:
>
> m_listener->chooseFiles(API::Array::create(WTFMove(urls)).get());
>
> > Source/WebKit2/UIProcess/Cocoa/WKConcreteOpenPanelResultListener.m:71
> > +- (void)cancel {
>
> Same threading issues apply here as in chooseFiles: and I think we should
> probably make these share code. Simplest way is probably to just implement
> this as [self chooseFiles:@[]] unless we change the semantics of chooseFiles
> to make choosing zero files something distinct from cancelling. In that case
> Iâm sure we can still find a way to share the tricky main thread code.
>
> WebKit coding style puts the open brace on a separate line.
>
> > Source/WebKit2/WebKit2.xcodeproj/project.pbxproj:1082
> > + 72C06CFF1C531D1A001291DE /* WKUIOpenPanelParametersPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 72C06CFE1C531D1A001291DE /* WKUIOpenPanelParametersPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
>
> We donât want this visible outside the framework, so it should be Internal,
> not private. The ATTRIBUTES = (Private, ) here is wrong.
>
> > Source/WebKit2/WebKit2.xcodeproj/project.pbxproj:1084
> > + 72FCB6B41C307C2B00E8A012 /* WKConcreteOpenPanelResultListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 72FCB6B11C307C2B00E8A012 /* WKConcreteOpenPanelResultListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
>
> We donât want this visible outside the framework, so it should be Internal,
> not private. The ATTRIBUTES = (Private, ) here is wrong.
>
> > Tools/ChangeLog:15
> > + * MiniBrowser/mac/WK2BrowserWindowController.m:
> > + (-[WK2BrowserWindowController webView:runOpenPanelWithResultListener:parameters:]):
> > + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
> > + * TestWebKitAPI/Tests/WebKit2/basic-input-element.html: Added.
> > + * TestWebKitAPI/Tests/WebKit2ObjC/WKUIDelegateOpenPanelTest.mm: Added.
> > + (-[WKOpenPanelTestDelegate webView:runOpenPanelWithResultListener:parameters:]):
> > + (-[WKOpenPanelTestDelegate webView:didFinishNavigation:]):
> > + (TestWebKitAPI::TEST):
>
> As above, a good quality change log should have comments about what each
> change was. Per-function comments help people understand the change. If you
> need an example, I suggest looking at change log entries I have written in
> the past to see what I am asking for.
>
> > Tools/ChangeLog:549
> > - I always forgot to provide a --jsc argument), I always found it easier to
> > + I always forgot to provide a --jsc argument), I always found it easier to
>
> As above, trimming all the trailing whitespace from the ChangeLog is not
> typically something we want to do; makes the patch bigger for no good reason.
>
> > Tools/MiniBrowser/mac/WK2BrowserWindowController.m:452
> > + [openPanel setAllowsMultipleSelection:parameters.allowsMultipleFiles];
>
> I would have written:
>
> openPanel.allowsMultipleSelection = parameters.allowsMultipleFiles;
>
> > Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKUIDelegateOpenPanelTest.mm:26
> > +#include "config.h"
>
> Should be #import.
>
> > Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKUIDelegateOpenPanelTest.mm:31
> > +#include <wtf/RetainPtr.h>
>
> Should be #import. Should be in the same paragraph with the other includes
> just above.
>
> > Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKUIDelegateOpenPanelTest.mm:33
> > +#if WK_API_ENABLED && !PLATFORM(IOS)
>
> Should use the same #if as the code. Since the code is in PLATFORM(MAC),
> then this should be PLATFORM(MAC), as opposed to !PLATFORM(IOS).
>
> > Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKUIDelegateOpenPanelTest.mm:36
> > +static bool doneOpening;
> > +static bool doneLoading;
>
> It might be cleaner to use public fields in WKOpenPanelTestDelegate instead
> of globals. Then we wouldnât have to clear them on the way out of the test.
> Not sure we need to do that anyway. But since itâs just a test, I think itâs
> OK either wya.
Darin, thank you so much for the feedback, I'll work on these changes and get them submitted by the end of the week!
--
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20160125/3cc02b43/attachment-0001.html>
More information about the webkit-unassigned
mailing list