Add IconLoadingDelegate functionality to WKView.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2017 06:16:42 +0000 (06:16 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2017 06:16:42 +0000 (06:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=166951

Reviewed by Tim Horton.

* UIProcess/API/mac/WKView.mm:
(-[WKView dealloc]):
(-[WKView maybeInstallIconLoadingClient]): If the subclass implements the delegate method, install the
  icon loading client. Otherwise, maintain the normal IconDatabase loading behavior.
(-[WKView initWithFrame:processPool:configuration:webView:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210624 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/mac/WKView.mm

index ee57547..565b03c 100644 (file)
@@ -1,3 +1,16 @@
+2017-01-11  Brady Eidson  <beidson@apple.com>
+
+        Add IconLoadingDelegate functionality to WKView.
+        https://bugs.webkit.org/show_bug.cgi?id=166951
+
+        Reviewed by Tim Horton.
+        
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView dealloc]):
+        (-[WKView maybeInstallIconLoadingClient]): If the subclass implements the delegate method, install the
+          icon loading client. Otherwise, maintain the normal IconDatabase loading behavior.
+        (-[WKView initWithFrame:processPool:configuration:webView:]):
+
 2017-01-11  Brent Fulgham  <bfulgham@apple.com>
 
         [WK2][Cocoa] Avoid null dereference in FullScreen code.
index 2fef1b0..580c870 100644 (file)
 #if PLATFORM(MAC)
 
 #import "APIHitTestResult.h"
+#import "APIIconLoadingClient.h"
 #import "APIPageConfiguration.h"
 #import "WKBrowsingContextGroupPrivate.h"
+#import "WKNSData.h"
 #import "WKProcessGroupPrivate.h"
 #import "WebBackForwardListItem.h"
 #import "WebKit2Initialize.h"
@@ -38,6 +40,8 @@
 #import "WebPreferencesKeys.h"
 #import "WebProcessPool.h"
 #import "WebViewImpl.h"
+#import "_WKLinkIconParametersInternal.h"
+#import <wtf/BlockPtr.h>
 
 using namespace WebKit;
 using namespace WebCore;
@@ -78,6 +82,7 @@ using namespace WebCore;
 
 - (void)dealloc
 {
+    _data->_impl->page().setIconLoadingClient(nullptr);
     _data->_impl = nullptr;
 
     [_data release];
@@ -848,6 +853,48 @@ Some other editing-related methods still unimplemented:
     return _data->_impl->namesOfPromisedFilesDroppedAtDestination(dropDestination);
 }
 
+- (void)maybeInstallIconLoadingClient
+{
+#if WK_API_ENABLED
+    class IconLoadingClient : public API::IconLoadingClient {
+    public:
+        explicit IconLoadingClient(WKView *wkView)
+            : m_wkView(wkView)
+        {
+        }
+
+        static SEL delegateSelector()
+        {
+            return sel_registerName("_shouldLoadIconWithParameters:completionHandler:");
+        }
+
+    private:
+        typedef void (^IconLoadCompletionHandler)(NSData*);
+
+        void getLoadDecisionForIcon(const WebCore::LinkIcon& linkIcon, Function<void (std::function<void (API::Data*, WebKit::CallbackBase::Error)>)>&& completionHandler) override {
+            RetainPtr<_WKLinkIconParameters> parameters = adoptNS([[_WKLinkIconParameters alloc] _initWithLinkIcon:linkIcon]);
+
+            [m_wkView performSelector:delegateSelector() withObject:parameters.get() withObject:^void (IconLoadCompletionHandler loadCompletionHandler) {
+                if (loadCompletionHandler) {
+                    completionHandler([loadCompletionHandler = BlockPtr<void (NSData *)>(loadCompletionHandler)](API::Data* data, WebKit::CallbackBase::Error error) {
+                        if (error != CallbackBase::Error::None || !data)
+                            loadCompletionHandler(nil);
+                        else
+                            loadCompletionHandler(wrapper(*data));
+                    });
+                } else
+                    completionHandler(nullptr);
+            }];
+        }
+
+        WKView *m_wkView;
+    };
+
+    if ([self respondsToSelector:IconLoadingClient::delegateSelector()])
+        _data->_impl->page().setIconLoadingClient(std::make_unique<IconLoadingClient>(self));
+#endif // WK_API_ENABLED
+}
+
 - (instancetype)initWithFrame:(NSRect)frame processPool:(WebProcessPool&)processPool configuration:(Ref<API::PageConfiguration>&&)configuration webView:(WKWebView *)webView
 {
     self = [super initWithFrame:frame];
@@ -859,6 +906,8 @@ Some other editing-related methods still unimplemented:
     _data = [[WKViewData alloc] init];
     _data->_impl = std::make_unique<WebViewImpl>(self, webView, processPool, WTFMove(configuration));
 
+    [self maybeInstallIconLoadingClient];
+
     return self;
 }