Changeset 238819 in webkit


Ignore:
Timestamp:
Dec 3, 2018, 1:47:08 PM (7 years ago)
Author:
achristensen@apple.com
Message:

Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler
https://bugs.webkit.org/show_bug.cgi?id=192272

Reviewed by Brady Eidson.

Source/WebCore:

This is needed for rdar://problem/45910057
Covered by an API test.

  • loader/EmptyFrameLoaderClient.h:
  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::prepareForLoadStart):
(WebCore::FrameLoader::continueLoadAfterNavigationPolicy):
(WebCore::FrameLoader::loadProvisionalItemFromCachedPage):

  • loader/FrameLoader.h:
  • loader/FrameLoaderClient.h:

Source/WebKit:

  • WebProcess/InjectedBundle/API/APIInjectedBundlePageLoaderClient.h:

(API::InjectedBundle::PageLoaderClient::didStartProvisionalLoadForFrame):

  • WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h:
  • WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp:
  • WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:

(ResourceLoadClient::ResourceLoadClient):
(ResourceLoadClient::loadDelegate const):
(ResourceLoadClient::pluginContextController const):
(PageLoaderClient::PageLoaderClient):
(PageLoaderClient::loadDelegate const):
(PageLoaderClient::pluginContextController const):
(PageLoaderClient::didStartProvisionalLoadForFrame):
(PageLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame):
(PageLoaderClient::didFinishLoadForFrame):
(PageLoaderClient::globalObjectIsAvailableForFrame):
(PageLoaderClient::didRemoveFrameFromHierarchy):
(PageLoaderClient::didCommitLoadForFrame):
(PageLoaderClient::didFinishDocumentLoadForFrame):
(PageLoaderClient::didFailProvisionalLoadWithErrorForFrame):
(PageLoaderClient::didFailLoadWithErrorForFrame):
(PageLoaderClient::didSameDocumentNavigationForFrame):
(PageLoaderClient::didLayoutForFrame):
(PageLoaderClient::didReachLayoutMilestone):
(PageLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame):
(PageLoaderClient::didHandleOnloadEventsForFrame):
(PageLoaderClient::userAgentForURL const):
(ResourceLoadClient::willSendRequestForFrame):
(ResourceLoadClient::didInitiateLoadForResource):
(ResourceLoadClient::didFinishLoadForResource):
(ResourceLoadClient::didFailLoadForResource):
(-[WKWebProcessPlugInBrowserContextController setLoadDelegate:]):
(didStartProvisionalLoadForFrame): Deleted.
(didReceiveServerRedirectForProvisionalLoadForFrame): Deleted.
(didFinishLoadForFrame): Deleted.
(globalObjectIsAvailableForFrame): Deleted.
(didRemoveFrameFromHierarchy): Deleted.
(didCommitLoadForFrame): Deleted.
(didFinishDocumentLoadForFrame): Deleted.
(didFailProvisionalLoadWithErrorForFrame): Deleted.
(didFailLoadWithErrorForFrame): Deleted.
(didSameDocumentNavigationForFrame): Deleted.
(didLayoutForFrame): Deleted.
(didReachLayoutMilestone): Deleted.
(didFirstVisuallyNonEmptyLayoutForFrame): Deleted.
(didHandleOnloadEventsForFrame): Deleted.
(userAgentForURL): Deleted.
(setUpPageLoaderClient): Deleted.
(willSendRequestForFrame): Deleted.
(didInitiateLoadForResource): Deleted.
(didFinishLoadForResource): Deleted.
(didFailLoadForResource): Deleted.
(setUpResourceLoadClient): Deleted.

  • WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp:

(WebKit::InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame):

  • WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h:
  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::dispatchDidStartProvisionalLoad):

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.h:

Source/WebKitLegacy/mac:

  • WebCoreSupport/WebFrameLoaderClient.h:
  • WebCoreSupport/WebFrameLoaderClient.mm:

(WebFrameLoaderClient::dispatchDidStartProvisionalLoad):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/ParserYieldTokenPlugIn.mm:

(-[ParserYieldTokenPlugIn webProcessPlugInBrowserContextController:willStartProvisionalLoadForFrame:completionHandler:]):
(-[ParserYieldTokenPlugIn webProcessPlugInBrowserContextController:didCommitLoadForFrame:]):

Location:
trunk
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238816 r238819  
     12018-12-03  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler
     4        https://bugs.webkit.org/show_bug.cgi?id=192272
     5
     6        Reviewed by Brady Eidson.
     7
     8        This is needed for rdar://problem/45910057
     9        Covered by an API test.
     10
     11        * loader/EmptyFrameLoaderClient.h:
     12        * loader/FrameLoader.cpp:
     13        (WebCore::FrameLoader::prepareForLoadStart):
     14        (WebCore::FrameLoader::continueLoadAfterNavigationPolicy):
     15        (WebCore::FrameLoader::loadProvisionalItemFromCachedPage):
     16        * loader/FrameLoader.h:
     17        * loader/FrameLoaderClient.h:
     18
    1192018-12-03  Zalan Bujtas  <zalan@apple.com>
    220
  • trunk/Source/WebCore/loader/EmptyFrameLoaderClient.h

    r238633 r238819  
    8282    void dispatchDidPopStateWithinPage() final { }
    8383    void dispatchWillClose() final { }
    84     void dispatchDidStartProvisionalLoad() final { }
     84    void dispatchDidStartProvisionalLoad(CompletionHandler<void()>&& completionHandler) final { completionHandler(); }
    8585    void dispatchDidReceiveTitle(const StringWithDirection&) final { }
    8686    void dispatchDidCommitLoad(std::optional<HasInsecureContent>) final { }
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r238787 r238819  
    12081208}
    12091209
    1210 void FrameLoader::prepareForLoadStart()
     1210void FrameLoader::prepareForLoadStart(CompletionHandler<void()>&& completionHandler)
    12111211{
    12121212    RELEASE_LOG_IF_ALLOWED("prepareForLoadStart: Starting frame load (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
    12131213
    12141214    m_progressTracker->progressStarted();
    1215     m_client.dispatchDidStartProvisionalLoad();
    1216 
    1217     if (AXObjectCache::accessibilityEnabled()) {
    1218         if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
    1219             AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
    1220             cache->frameLoadingEventNotification(&m_frame, loadingEvent);
     1215    m_client.dispatchDidStartProvisionalLoad([this, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
     1216        if (AXObjectCache::accessibilityEnabled()) {
     1217            if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
     1218                AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
     1219                cache->frameLoadingEventNotification(&m_frame, loadingEvent);
     1220            }
    12211221        }
    1222     }
     1222        completionHandler();
     1223    });
    12231224}
    12241225
     
    33423343    }
    33433344
    3344     CompletionHandler<void()> completionHandler = [this, shouldContinue] {
     3345    CompletionHandler<void()> completionHandler = [this, protectedFrame = makeRef(m_frame), shouldContinue] () mutable {
    33453346        if (!m_provisionalDocumentLoader)
    33463347            return;
    33473348       
    3348         prepareForLoadStart();
    3349        
    3350         // The load might be cancelled inside of prepareForLoadStart(), nulling out the m_provisionalDocumentLoader,
    3351         // so we need to null check it again.
    3352         if (!m_provisionalDocumentLoader) {
    3353             RELEASE_LOG_IF_ALLOWED("dispatchWillSubmitForm completionHandler: Frame load canceled (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
    3354             return;
    3355         }
    3356        
    3357         DocumentLoader* activeDocLoader = activeDocumentLoader();
    3358         if (activeDocLoader && activeDocLoader->isLoadingMainResource()) {
    3359             RELEASE_LOG_IF_ALLOWED("dispatchWillSubmitForm completionHandler: Main frame already being loaded (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
    3360             return;
    3361         }
    3362        
    3363         m_loadingFromCachedPage = false;
    3364 
    3365         // We handle suspension by navigating forward to about:blank, which leaves us setup to navigate back to resume.
    3366         if (shouldContinue == ShouldContinue::ForSuspension) {
    3367             // Make sure we do a standard load to about:blank instead of reusing whatever the load type was on process swap.
    3368             // For example, using a Back/Forward load to load about blank would cause the current HistoryItem's url to be
    3369             // overwritten with 'about:blank', which we do not want.
    3370             m_loadType = FrameLoadType::Standard;
    3371             m_provisionalDocumentLoader->willContinueMainResourceLoadAfterRedirect({ WTF::blankURL() });
    3372         }
    3373 
    3374         m_provisionalDocumentLoader->startLoadingMainResource(shouldContinue);
     3349        prepareForLoadStart([this, protectedFrame = WTFMove(protectedFrame), shouldContinue] {
     3350
     3351            // The load might be cancelled inside of prepareForLoadStart(), nulling out the m_provisionalDocumentLoader,
     3352            // so we need to null check it again.
     3353            if (!m_provisionalDocumentLoader) {
     3354                RELEASE_LOG_IF_ALLOWED("dispatchWillSubmitForm completionHandler: Frame load canceled (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
     3355                return;
     3356            }
     3357           
     3358            DocumentLoader* activeDocLoader = activeDocumentLoader();
     3359            if (activeDocLoader && activeDocLoader->isLoadingMainResource()) {
     3360                RELEASE_LOG_IF_ALLOWED("dispatchWillSubmitForm completionHandler: Main frame already being loaded (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
     3361                return;
     3362            }
     3363           
     3364            m_loadingFromCachedPage = false;
     3365
     3366            // We handle suspension by navigating forward to about:blank, which leaves us setup to navigate back to resume.
     3367            if (shouldContinue == ShouldContinue::ForSuspension) {
     3368                // Make sure we do a standard load to about:blank instead of reusing whatever the load type was on process swap.
     3369                // For example, using a Back/Forward load to load about blank would cause the current HistoryItem's url to be
     3370                // overwritten with 'about:blank', which we do not want.
     3371                m_loadType = FrameLoadType::Standard;
     3372                m_provisionalDocumentLoader->willContinueMainResourceLoadAfterRedirect({ WTF::blankURL() });
     3373            }
     3374
     3375            m_provisionalDocumentLoader->startLoadingMainResource(shouldContinue);
     3376        });
    33753377    };
    33763378   
     
    35153517void FrameLoader::loadProvisionalItemFromCachedPage()
    35163518{
    3517     DocumentLoader* provisionalLoader = provisionalDocumentLoader();
    3518     LOG(PageCache, "WebCorePageCache: Loading provisional DocumentLoader %p with URL '%s' from CachedPage", provisionalDocumentLoader(), provisionalDocumentLoader()->url().stringCenterEllipsizedToLength().utf8().data());
    3519 
    3520     prepareForLoadStart();
    3521 
    3522     m_loadingFromCachedPage = true;
    3523 
    3524     // Should have timing data from previous time(s) the page was shown.
    3525     ASSERT(provisionalLoader->timing().startTime());
    3526     provisionalLoader->resetTiming();
    3527     provisionalLoader->timing().markStartTime();
    3528 
    3529     provisionalLoader->setCommitted(true);
    3530     commitProvisionalLoad();
     3519    prepareForLoadStart([this, protectedFrame = makeRef(m_frame)] {
     3520        DocumentLoader* provisionalLoader = provisionalDocumentLoader();
     3521        LOG(PageCache, "WebCorePageCache: Loading provisional DocumentLoader %p with URL '%s' from CachedPage", provisionalDocumentLoader(), provisionalDocumentLoader()->url().stringCenterEllipsizedToLength().utf8().data());
     3522
     3523        m_loadingFromCachedPage = true;
     3524       
     3525        // Should have timing data from previous time(s) the page was shown.
     3526        ASSERT(provisionalLoader->timing().startTime());
     3527        provisionalLoader->resetTiming();
     3528        provisionalLoader->timing().markStartTime();
     3529       
     3530        provisionalLoader->setCommitted(true);
     3531        commitProvisionalLoad();
     3532    });
    35313533}
    35323534
  • trunk/Source/WebCore/loader/FrameLoader.h

    r238755 r238819  
    388388    void loadInSameDocument(const URL&, SerializedScriptValue* stateObject, bool isNewNavigation);
    389389
    390     void prepareForLoadStart();
     390    void prepareForLoadStart(CompletionHandler<void()>&&);
    391391    void provisionalLoadStarted();
    392392
  • trunk/Source/WebCore/loader/FrameLoaderClient.h

    r238771 r238819  
    174174    virtual void dispatchWillClose() = 0;
    175175    virtual void dispatchDidReceiveIcon() { }
    176     virtual void dispatchDidStartProvisionalLoad() = 0;
     176    virtual void dispatchDidStartProvisionalLoad(CompletionHandler<void()>&&) = 0;
    177177    virtual void dispatchDidReceiveTitle(const StringWithDirection&) = 0;
    178178    virtual void dispatchDidCommitLoad(std::optional<HasInsecureContent>) = 0;
  • trunk/Source/WebKit/ChangeLog

    r238818 r238819  
     12018-12-03  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler
     4        https://bugs.webkit.org/show_bug.cgi?id=192272
     5
     6        Reviewed by Brady Eidson.
     7
     8        * WebProcess/InjectedBundle/API/APIInjectedBundlePageLoaderClient.h:
     9        (API::InjectedBundle::PageLoaderClient::didStartProvisionalLoadForFrame):
     10        * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h:
     11        * WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp:
     12        * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
     13        (ResourceLoadClient::ResourceLoadClient):
     14        (ResourceLoadClient::loadDelegate const):
     15        (ResourceLoadClient::pluginContextController const):
     16        (PageLoaderClient::PageLoaderClient):
     17        (PageLoaderClient::loadDelegate const):
     18        (PageLoaderClient::pluginContextController const):
     19        (PageLoaderClient::didStartProvisionalLoadForFrame):
     20        (PageLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame):
     21        (PageLoaderClient::didFinishLoadForFrame):
     22        (PageLoaderClient::globalObjectIsAvailableForFrame):
     23        (PageLoaderClient::didRemoveFrameFromHierarchy):
     24        (PageLoaderClient::didCommitLoadForFrame):
     25        (PageLoaderClient::didFinishDocumentLoadForFrame):
     26        (PageLoaderClient::didFailProvisionalLoadWithErrorForFrame):
     27        (PageLoaderClient::didFailLoadWithErrorForFrame):
     28        (PageLoaderClient::didSameDocumentNavigationForFrame):
     29        (PageLoaderClient::didLayoutForFrame):
     30        (PageLoaderClient::didReachLayoutMilestone):
     31        (PageLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame):
     32        (PageLoaderClient::didHandleOnloadEventsForFrame):
     33        (PageLoaderClient::userAgentForURL const):
     34        (ResourceLoadClient::willSendRequestForFrame):
     35        (ResourceLoadClient::didInitiateLoadForResource):
     36        (ResourceLoadClient::didFinishLoadForResource):
     37        (ResourceLoadClient::didFailLoadForResource):
     38        (-[WKWebProcessPlugInBrowserContextController setLoadDelegate:]):
     39        (didStartProvisionalLoadForFrame): Deleted.
     40        (didReceiveServerRedirectForProvisionalLoadForFrame): Deleted.
     41        (didFinishLoadForFrame): Deleted.
     42        (globalObjectIsAvailableForFrame): Deleted.
     43        (didRemoveFrameFromHierarchy): Deleted.
     44        (didCommitLoadForFrame): Deleted.
     45        (didFinishDocumentLoadForFrame): Deleted.
     46        (didFailProvisionalLoadWithErrorForFrame): Deleted.
     47        (didFailLoadWithErrorForFrame): Deleted.
     48        (didSameDocumentNavigationForFrame): Deleted.
     49        (didLayoutForFrame): Deleted.
     50        (didReachLayoutMilestone): Deleted.
     51        (didFirstVisuallyNonEmptyLayoutForFrame): Deleted.
     52        (didHandleOnloadEventsForFrame): Deleted.
     53        (userAgentForURL): Deleted.
     54        (setUpPageLoaderClient): Deleted.
     55        (willSendRequestForFrame): Deleted.
     56        (didInitiateLoadForResource): Deleted.
     57        (didFinishLoadForResource): Deleted.
     58        (didFailLoadForResource): Deleted.
     59        (setUpResourceLoadClient): Deleted.
     60        * WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp:
     61        (WebKit::InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame):
     62        * WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h:
     63        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     64        (WebKit::WebFrameLoaderClient::dispatchDidStartProvisionalLoad):
     65        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
     66
    1672018-12-03  Tim Horton  <timothy_horton@apple.com>
    268
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/APIInjectedBundlePageLoaderClient.h

    r238771 r238819  
    2828#include "SameDocumentNavigationType.h"
    2929#include <WebCore/LayoutMilestone.h>
     30#include <wtf/CompletionHandler.h>
    3031#include <wtf/Forward.h>
    3132#include <wtf/WallTime.h>
     
    5859    virtual void willLoadDataRequest(WebKit::WebPage&, const WebCore::ResourceRequest&, WebCore::SharedBuffer*, const WTF::String&, const WTF::String&, const WTF::URL&, API::Object*) { }
    5960
    60     virtual void didStartProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) { }
     61    virtual void didStartProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, CompletionHandler<void(RefPtr<API::Object>&&)>&& completionHandler) { completionHandler(nullptr); }
    6162    virtual void didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) { }
    6263    virtual void didFailProvisionalLoadWithErrorForFrame(WebKit::WebPage&, WebKit::WebFrame&, const WebCore::ResourceError&, RefPtr<API::Object>&) { }
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h

    r182267 r238819  
    3838
    3939- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didStartProvisionalLoadForFrame:(WKWebProcessPlugInFrame *)frame;
     40- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller willStartProvisionalLoadForFrame:(WKWebProcessPlugInFrame *)frame completionHandler:(void(^)(void))completionHandler;
    4041- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didReceiveServerRedirectForProvisionalLoadForFrame:(WKWebProcessPlugInFrame *)frame;
    4142- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didCommitLoadForFrame:(WKWebProcessPlugInFrame *)frame;
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp

    r235909 r238819  
    171171    }
    172172
    173     void didStartProvisionalLoadForFrame(WebPage&, WebFrame& frame, RefPtr<API::Object>&) override
     173    void didStartProvisionalLoadForFrame(WebPage&, WebFrame& frame, CompletionHandler<void(RefPtr<API::Object>&&)>&& completionHandler) override
    174174    {
    175175        if (!frame.isMainFrame())
    176             return;
     176            return completionHandler(nullptr);
    177177        webkitWebPageSetURI(m_webPage, getDocumentLoaderURL(frame.coreFrame()->loader().provisionalDocumentLoader()));
     178        completionHandler(nullptr);
    178179    }
    179180
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm

    r237266 r238819  
    3030
    3131#import "APIData.h"
     32#import "CompletionHandlerCallChecker.h"
    3233#import "RemoteObjectRegistry.h"
    3334#import "RemoteObjectRegistryMessages.h"
     
    6566#import <WebCore/HTMLInputElement.h>
    6667#import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
     68#import <wtf/BlockPtr.h>
    6769#import <wtf/WeakObjCPtr.h>
    6870
     
    7072- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didSameDocumentNavigationForFrame:(WKWebProcessPlugInFrame *)frame;
    7173@end
     74
     75class ResourceLoadClient : public API::InjectedBundle::ResourceLoadClient {
     76public:
     77    explicit ResourceLoadClient(WKWebProcessPlugInBrowserContextController *controller, id <WKWebProcessPlugInLoadDelegate> delegate)
     78        : m_controller(controller)
     79        , m_delegate(delegate) { }
     80   
     81    void didInitiateLoadForResource(WebKit::WebPage&, WebKit::WebFrame&, uint64_t identifier, const WebCore::ResourceRequest&, bool) override;
     82    void willSendRequestForFrame(WebKit::WebPage&, WebKit::WebFrame&, uint64_t identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse&) override;
     83    void didFinishLoadForResource(WebKit::WebPage&, WebKit::WebFrame&, uint64_t identifier) override;
     84    void didFailLoadForResource(WebKit::WebPage&, WebKit::WebFrame&, uint64_t identifier, const WebCore::ResourceError&) override;
     85
     86private:
     87    id <WKWebProcessPlugInLoadDelegate> loadDelegate() const { return m_delegate.get().get(); }
     88    WKWebProcessPlugInBrowserContextController *pluginContextController() const { return m_controller.get().get(); }
     89   
     90    WeakObjCPtr<WKWebProcessPlugInBrowserContextController> m_controller;
     91    WeakObjCPtr<id <WKWebProcessPlugInLoadDelegate>> m_delegate;
     92};
     93
     94class PageLoaderClient : public API::InjectedBundle::PageLoaderClient {
     95public:
     96    explicit PageLoaderClient(WKWebProcessPlugInBrowserContextController *controller, id <WKWebProcessPlugInLoadDelegate> delegate)
     97        : m_controller(controller)
     98        , m_delegate(delegate) { }
     99   
     100    void didStartProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, CompletionHandler<void(RefPtr<API::Object>&&)>&&) override;
     101    void didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     102    void didFailProvisionalLoadWithErrorForFrame(WebKit::WebPage&, WebKit::WebFrame&, const WebCore::ResourceError&, RefPtr<API::Object>&) override;
     103    void didCommitLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     104    void didFinishDocumentLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     105    void didFinishLoadForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     106    void didFailLoadWithErrorForFrame(WebKit::WebPage&, WebKit::WebFrame&, const WebCore::ResourceError&, RefPtr<API::Object>&) override;
     107    void didSameDocumentNavigationForFrame(WebKit::WebPage&, WebKit::WebFrame&, WebKit::SameDocumentNavigationType, RefPtr<API::Object>&) override;
     108    void didRemoveFrameFromHierarchy(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     109   
     110    void didFirstVisuallyNonEmptyLayoutForFrame(WebKit::WebPage&, WebKit::WebFrame&, RefPtr<API::Object>&) override;
     111    void didLayoutForFrame(WebKit::WebPage&, WebKit::WebFrame&) override;
     112    void didReachLayoutMilestone(WebKit::WebPage&, OptionSet<WebCore::LayoutMilestone>, RefPtr<API::Object>&) override;
     113   
     114    void didHandleOnloadEventsForFrame(WebKit::WebPage&, WebKit::WebFrame&) override;
     115   
     116    void globalObjectIsAvailableForFrame(WebKit::WebPage&, WebKit::WebFrame&, WebCore::DOMWrapperWorld&) override;
     117
     118    WTF::String userAgentForURL(WebKit::WebFrame&, const URL&) const override;
     119   
     120private:
     121    id <WKWebProcessPlugInLoadDelegate> loadDelegate() const { return m_delegate.get().get(); }
     122    WKWebProcessPlugInBrowserContextController *pluginContextController() const { return m_controller.get().get(); }
     123
     124    WeakObjCPtr<WKWebProcessPlugInBrowserContextController> m_controller;
     125    WeakObjCPtr<id <WKWebProcessPlugInLoadDelegate>> m_delegate;
     126};
    72127
    73128@implementation WKWebProcessPlugInBrowserContextController {
     
    80135}
    81136
    82 static void didStartProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userDataRef, const void *clientInfo)
    83 {
    84     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    85     auto loadDelegate = pluginContextController->_loadDelegate.get();
    86 
    87     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didStartProvisionalLoadForFrame:)])
    88         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didStartProvisionalLoadForFrame:wrapper(*WebKit::toImpl(frame))];
    89 }
    90 
    91 static void didReceiveServerRedirectForProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef *userDataRef, const void *clientInfo)
    92 {
    93     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    94     auto loadDelegate = pluginContextController->_loadDelegate.get();
    95 
    96     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didReceiveServerRedirectForProvisionalLoadForFrame:)])
    97         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didReceiveServerRedirectForProvisionalLoadForFrame:wrapper(*WebKit::toImpl(frame))];
    98 }
    99 
    100 static void didFinishLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo)
    101 {
    102     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    103     auto loadDelegate = pluginContextController->_loadDelegate.get();
    104 
    105     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFinishLoadForFrame:)])
    106         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFinishLoadForFrame:wrapper(*WebKit::toImpl(frame))];
    107 }
    108 
    109 static void globalObjectIsAvailableForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef scriptWorld, const void* clientInfo)
    110 {
    111     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    112     auto loadDelegate = pluginContextController->_loadDelegate.get();
    113 
    114     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:globalObjectIsAvailableForFrame:inScriptWorld:)])
    115         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController globalObjectIsAvailableForFrame:wrapper(*WebKit::toImpl(frame)) inScriptWorld:wrapper(*WebKit::toImpl(scriptWorld))];
    116 }
    117 
    118 static void didRemoveFrameFromHierarchy(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void* clientInfo)
    119 {
    120     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    121     auto loadDelegate = pluginContextController->_loadDelegate.get();
    122 
    123     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didRemoveFrameFromHierarchy:)])
    124         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didRemoveFrameFromHierarchy:wrapper(*WebKit::toImpl(frame))];
    125 }
    126 
    127 static void didCommitLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo)
    128 {
    129     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    130     auto loadDelegate = pluginContextController->_loadDelegate.get();
    131 
    132     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didCommitLoadForFrame:)])
    133         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didCommitLoadForFrame:wrapper(*WebKit::toImpl(frame))];
    134 }
    135 
    136 static void didFinishDocumentLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo)
    137 {
    138     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    139     auto loadDelegate = pluginContextController->_loadDelegate.get();
    140 
    141     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFinishDocumentLoadForFrame:)])
    142         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFinishDocumentLoadForFrame:wrapper(*WebKit::toImpl(frame))];
    143 }
    144 
    145 static void didFailProvisionalLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef wkError, WKTypeRef* userData, const void *clientInfo)
    146 {
    147     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    148     auto loadDelegate = pluginContextController->_loadDelegate.get();
    149 
    150     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFailProvisionalLoadWithErrorForFrame:error:)])
    151         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFailProvisionalLoadWithErrorForFrame:wrapper(*WebKit::toImpl(frame)) error:wrapper(*WebKit::toImpl(wkError))];
    152 }
    153 
    154 static void didFailLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef wkError, WKTypeRef* userData, const void *clientInfo)
    155 {
    156     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    157     auto loadDelegate = pluginContextController->_loadDelegate.get();
    158 
    159     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFailLoadWithErrorForFrame:error:)])
    160         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFailLoadWithErrorForFrame:wrapper(*WebKit::toImpl(frame)) error:wrapper(*WebKit::toImpl(wkError))];
    161 }
    162 
    163 static void didSameDocumentNavigationForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef* userData, const void *clientInfo)
    164 {
    165     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    166     auto loadDelegate = pluginContextController->_loadDelegate.get();
    167 
    168     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didSameDocumentNavigation:forFrame:)])
    169         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didSameDocumentNavigation:toWKSameDocumentNavigationType(WebKit::toSameDocumentNavigationType(type)) forFrame:wrapper(*WebKit::toImpl(frame))];
     137void PageLoaderClient::didStartProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, CompletionHandler<void(RefPtr<API::Object>&&)>&& completionHandler)
     138{
     139    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didStartProvisionalLoadForFrame:)]) {
     140        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didStartProvisionalLoadForFrame:wrapper(frame)];
     141        completionHandler(nullptr);
     142        return;
     143    }
     144    SEL selector = @selector(webProcessPlugInBrowserContextController:willStartProvisionalLoadForFrame:completionHandler:);
     145    if ([loadDelegate() respondsToSelector:selector]) {
     146        auto checker = WebKit::CompletionHandlerCallChecker::create(loadDelegate(), selector);
     147        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() willStartProvisionalLoadForFrame:wrapper(frame) completionHandler:BlockPtr<void()>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] () mutable {
     148            if (checker->completionHandlerHasBeenCalled())
     149                return;
     150            checker->didCallCompletionHandler();
     151            completionHandler(nullptr);
     152        }).get()];
     153        return;
     154    }
     155    completionHandler(nullptr);
     156}
     157
     158void PageLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     159{
     160    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didReceiveServerRedirectForProvisionalLoadForFrame:)])
     161        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didReceiveServerRedirectForProvisionalLoadForFrame:wrapper(frame)];
     162}
     163
     164void PageLoaderClient::didFinishLoadForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     165{
     166    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFinishLoadForFrame:)])
     167        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didFinishLoadForFrame:wrapper(frame)];
     168}
     169
     170void PageLoaderClient::globalObjectIsAvailableForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, WebCore::DOMWrapperWorld& scriptWorld)
     171{
     172    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:globalObjectIsAvailableForFrame:inScriptWorld:)])
     173        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() globalObjectIsAvailableForFrame:wrapper(frame) inScriptWorld:API::wrapper(WebKit::InjectedBundleScriptWorld::getOrCreate(scriptWorld))];
     174}
     175
     176void PageLoaderClient::didRemoveFrameFromHierarchy(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     177{
     178    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didRemoveFrameFromHierarchy:)])
     179        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didRemoveFrameFromHierarchy:wrapper(frame)];
     180}
     181
     182void PageLoaderClient::didCommitLoadForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     183{
     184    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didCommitLoadForFrame:)])
     185        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didCommitLoadForFrame:wrapper(frame)];
     186}
     187
     188void PageLoaderClient::didFinishDocumentLoadForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     189{
     190    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFinishDocumentLoadForFrame:)])
     191        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didFinishDocumentLoadForFrame:wrapper(frame)];
     192}
     193
     194void PageLoaderClient::didFailProvisionalLoadWithErrorForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, const WebCore::ResourceError& error, RefPtr<API::Object>&)
     195{
     196    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFailProvisionalLoadWithErrorForFrame:error:)])
     197        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didFailProvisionalLoadWithErrorForFrame:wrapper(frame) error:error];
     198}
     199
     200void PageLoaderClient::didFailLoadWithErrorForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, const WebCore::ResourceError& error, RefPtr<API::Object>&)
     201{
     202    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFailLoadWithErrorForFrame:error:)])
     203        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didFailLoadWithErrorForFrame:wrapper(frame) error:error];
     204}
     205
     206void PageLoaderClient::didSameDocumentNavigationForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, WebKit::SameDocumentNavigationType type, RefPtr<API::Object>&)
     207{
     208    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didSameDocumentNavigation:forFrame:)])
     209        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didSameDocumentNavigation:toWKSameDocumentNavigationType(type) forFrame:wrapper(frame)];
    170210    else {
    171211        // FIXME: Remove this once clients switch to implementing the above delegate method.
    172         if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didSameDocumentNavigationForFrame:)])
    173             [(NSObject *)loadDelegate webProcessPlugInBrowserContextController:pluginContextController didSameDocumentNavigationForFrame:wrapper(*WebKit::toImpl(frame))];
    174     }
    175 }
    176 
    177 static void didLayoutForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo)
    178 {
    179     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    180     auto loadDelegate = pluginContextController->_loadDelegate.get();
    181 
    182     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didLayoutForFrame:)])
    183         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didLayoutForFrame:wrapper(*WebKit::toImpl(frame))];
    184 }
    185 
    186 static void didReachLayoutMilestone(WKBundlePageRef page, WKLayoutMilestones milestones, WKTypeRef* userData, const void *clientInfo)
    187 {
    188     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    189     auto loadDelegate = pluginContextController->_loadDelegate.get();
    190 
    191     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:renderingProgressDidChange:)])
    192         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController renderingProgressDidChange:renderingProgressEvents(WebKit::toLayoutMilestones(milestones))];
    193 }
    194 
    195 static void didFirstVisuallyNonEmptyLayoutForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo)
    196 {
    197     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    198     auto loadDelegate = pluginContextController->_loadDelegate.get();
    199 
    200     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFirstVisuallyNonEmptyLayoutForFrame:)])
    201         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFirstVisuallyNonEmptyLayoutForFrame:wrapper(*WebKit::toImpl(frame))];
    202 }
    203 
    204 static void didHandleOnloadEventsForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo)
    205 {
    206     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    207     auto loadDelegate = pluginContextController->_loadDelegate.get();
    208 
    209     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didHandleOnloadEventsForFrame:)])
    210         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didHandleOnloadEventsForFrame:wrapper(*WebKit::toImpl(frame))];
    211 }
    212 
    213 static WKStringRef userAgentForURL(WKBundleFrameRef frame, WKURLRef url, const void* clientInfo)
    214 {
    215     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    216     auto loadDelegate = pluginContextController->_loadDelegate.get();
    217    
    218     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:userAgentForURL:)]) {
    219         WKWebProcessPlugInFrame *newFrame = wrapper(*WebKit::toImpl(frame));
    220         NSString *string = [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:newFrame userAgentForURL:wrapper(*WebKit::toImpl(url))];
    221         if (!string)
    222             return nullptr;
    223 
    224         return WKStringCreateWithCFString((__bridge CFStringRef)string);
    225     }
    226    
    227     return nullptr;
    228 }
    229 
    230 static void setUpPageLoaderClient(WKWebProcessPlugInBrowserContextController *contextController, WebKit::WebPage& page)
    231 {
    232     WKBundlePageLoaderClientV9 client;
    233     memset(&client, 0, sizeof(client));
    234 
    235     client.base.version = 8;
    236     client.base.clientInfo = (__bridge void*)contextController;
    237     client.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
    238     client.didReceiveServerRedirectForProvisionalLoadForFrame = didReceiveServerRedirectForProvisionalLoadForFrame;
    239     client.didCommitLoadForFrame = didCommitLoadForFrame;
    240     client.didFinishDocumentLoadForFrame = didFinishDocumentLoadForFrame;
    241     client.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame;
    242     client.didFailLoadWithErrorForFrame = didFailLoadWithErrorForFrame;
    243     client.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame;
    244     client.didFinishLoadForFrame = didFinishLoadForFrame;
    245     client.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrame;
    246     client.didRemoveFrameFromHierarchy = didRemoveFrameFromHierarchy;
    247     client.didHandleOnloadEventsForFrame = didHandleOnloadEventsForFrame;
    248     client.didFirstVisuallyNonEmptyLayoutForFrame = didFirstVisuallyNonEmptyLayoutForFrame;
    249     client.userAgentForURL = userAgentForURL;
    250 
    251     client.didLayoutForFrame = didLayoutForFrame;
    252     client.didLayout = didReachLayoutMilestone;
    253 
    254     WKBundlePageSetPageLoaderClient(toAPI(&page), &client.base);
    255 }
    256 
    257 static WKURLRequestRef willSendRequestForFrame(WKBundlePageRef, WKBundleFrameRef frame, uint64_t resourceIdentifier, WKURLRequestRef request, WKURLResponseRef redirectResponse, const void* clientInfo)
    258 {
    259     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    260     auto loadDelegate = pluginContextController->_loadDelegate.get();
    261 
    262     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:willSendRequestForResource:request:redirectResponse:)]) {
    263         NSURLRequest *originalRequest = wrapper(*WebKit::toImpl(request));
    264         RetainPtr<NSURLRequest> substituteRequest = [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) willSendRequestForResource:resourceIdentifier
    265             request:originalRequest redirectResponse:WebKit::toImpl(redirectResponse)->resourceResponse().nsURLResponse()];
    266 
    267         if (substituteRequest != originalRequest)
    268             return substituteRequest ? WKURLRequestCreateWithNSURLRequest(substituteRequest.get()) : nullptr;
    269     } else if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:willSendRequest:redirectResponse:)]) {
    270         NSURLRequest *originalRequest = wrapper(*WebKit::toImpl(request));
    271         RetainPtr<NSURLRequest> substituteRequest = [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) willSendRequest:originalRequest
    272             redirectResponse:WebKit::toImpl(redirectResponse)->resourceResponse().nsURLResponse()];
    273 
    274         if (substituteRequest != originalRequest)
    275             return substituteRequest ? WKURLRequestCreateWithNSURLRequest(substituteRequest.get()) : nullptr;
    276     }
    277 
    278     WKRetain(request);
    279     return request;
    280 }
    281 
    282 static void didInitiateLoadForResource(WKBundlePageRef, WKBundleFrameRef frame, uint64_t resourceIdentifier, WKURLRequestRef request, bool pageIsProvisionallyLoading, const void* clientInfo)
    283 {
    284     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    285     auto loadDelegate = pluginContextController->_loadDelegate.get();
    286 
    287     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didInitiateLoadForResource:request:pageIsProvisionallyLoading:)]) {
    288         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) didInitiateLoadForResource:resourceIdentifier request:wrapper(*WebKit::toImpl(request))
     212        if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didSameDocumentNavigationForFrame:)])
     213            [(NSObject *)loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didSameDocumentNavigationForFrame:wrapper(frame)];
     214    }
     215}
     216
     217void PageLoaderClient::didLayoutForFrame(WebKit::WebPage&, WebKit::WebFrame& frame)
     218{
     219    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didLayoutForFrame:)])
     220        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didLayoutForFrame:wrapper(frame)];
     221}
     222
     223void PageLoaderClient::didReachLayoutMilestone(WebKit::WebPage&, OptionSet<WebCore::LayoutMilestone> milestones, RefPtr<API::Object>&)
     224{
     225    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:renderingProgressDidChange:)])
     226        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() renderingProgressDidChange:renderingProgressEvents(milestones)];
     227}
     228
     229void PageLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, RefPtr<API::Object>&)
     230{
     231    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didFirstVisuallyNonEmptyLayoutForFrame:)])
     232        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didFirstVisuallyNonEmptyLayoutForFrame:wrapper(frame)];
     233}
     234
     235void PageLoaderClient::didHandleOnloadEventsForFrame(WebKit::WebPage&, WebKit::WebFrame& frame)
     236{
     237    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:didHandleOnloadEventsForFrame:)])
     238        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() didHandleOnloadEventsForFrame:wrapper(frame)];
     239}
     240
     241WTF::String PageLoaderClient::userAgentForURL(WebKit::WebFrame& frame, const URL& url) const
     242{
     243    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:userAgentForURL:)])
     244        return [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) userAgentForURL:url];
     245    return { };
     246}
     247
     248void ResourceLoadClient::willSendRequestForFrame(WebKit::WebPage&, WebKit::WebFrame& frame, uint64_t resourceIdentifier, WebCore::ResourceRequest& request, const WebCore::ResourceResponse& redirectResponse)
     249{
     250    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:willSendRequestForResource:request:redirectResponse:)]) {
     251        RetainPtr<NSURLRequest> originalRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
     252        RetainPtr<NSURLRequest> substituteRequest = [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) willSendRequestForResource:resourceIdentifier
     253            request:originalRequest.get() redirectResponse:redirectResponse.nsURLResponse()];
     254
     255        if (substituteRequest != originalRequest) {
     256            request = substituteRequest.get();
     257            return;
     258        }
     259    } else if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:willSendRequest:redirectResponse:)]) {
     260        RetainPtr<NSURLRequest> originalRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
     261        RetainPtr<NSURLRequest> substituteRequest = [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) willSendRequest:originalRequest.get()
     262            redirectResponse:redirectResponse.nsURLResponse()];
     263
     264        if (substituteRequest != originalRequest) {
     265            request = substituteRequest.get();
     266            return;
     267        }
     268    }
     269}
     270
     271void ResourceLoadClient::didInitiateLoadForResource(WebKit::WebPage&, WebKit::WebFrame& frame, uint64_t resourceIdentifier, const WebCore::ResourceRequest& request, bool pageIsProvisionallyLoading)
     272{
     273    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didInitiateLoadForResource:request:pageIsProvisionallyLoading:)]) {
     274        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) didInitiateLoadForResource:resourceIdentifier request:request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)
    289275            pageIsProvisionallyLoading:pageIsProvisionallyLoading];
    290     } else if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didInitiateLoadForResource:request:)]) {
    291         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) didInitiateLoadForResource:resourceIdentifier request:wrapper(*WebKit::toImpl(request))];
    292     }
    293 }
    294 
    295 static void didFinishLoadForResource(WKBundlePageRef, WKBundleFrameRef frame, uint64_t resourceIdentifier, const void* clientInfo)
    296 {
    297     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    298     auto loadDelegate = pluginContextController->_loadDelegate.get();
    299 
    300     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didFinishLoadForResource:)]) {
    301         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) didFinishLoadForResource:resourceIdentifier];
    302     }
    303 }
    304 
    305 static void didFailLoadForResource(WKBundlePageRef, WKBundleFrameRef frame, uint64_t resourceIdentifier, WKErrorRef error, const void* clientInfo)
    306 {
    307     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
    308     auto loadDelegate = pluginContextController->_loadDelegate.get();
    309 
    310     if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didFailLoadForResource:error:)]) {
    311         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController frame:wrapper(*WebKit::toImpl(frame)) didFailLoadForResource:resourceIdentifier error:wrapper(*WebKit::toImpl(error))];
    312     }
    313 }
    314 
    315 static void setUpResourceLoadClient(WKWebProcessPlugInBrowserContextController *contextController, WebKit::WebPage& page)
    316 {
    317     WKBundlePageResourceLoadClientV1 client;
    318     memset(&client, 0, sizeof(client));
    319 
    320     client.base.version = 1;
    321     client.base.clientInfo = (__bridge void*) contextController;
    322     client.willSendRequestForFrame = willSendRequestForFrame;
    323     client.didInitiateLoadForResource = didInitiateLoadForResource;
    324     client.didFinishLoadForResource = didFinishLoadForResource;
    325     client.didFailLoadForResource = didFailLoadForResource;
    326 
    327     WKBundlePageSetResourceLoadClient(toAPI(&page), &client.base);
     276    } else if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didInitiateLoadForResource:request:)]) {
     277        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) didInitiateLoadForResource:resourceIdentifier request:request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)];
     278    }
     279}
     280
     281void ResourceLoadClient::didFinishLoadForResource(WebKit::WebPage&, WebKit::WebFrame& frame, uint64_t resourceIdentifier)
     282{
     283    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didFinishLoadForResource:)]) {
     284        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) didFinishLoadForResource:resourceIdentifier];
     285    }
     286}
     287
     288void ResourceLoadClient::didFailLoadForResource(WebKit::WebPage&, WebKit::WebFrame& frame, uint64_t resourceIdentifier, const WebCore::ResourceError& error)
     289{
     290    if ([loadDelegate() respondsToSelector:@selector(webProcessPlugInBrowserContextController:frame:didFailLoadForResource:error:)]) {
     291        [loadDelegate() webProcessPlugInBrowserContextController:pluginContextController() frame:wrapper(frame) didFailLoadForResource:resourceIdentifier error:error];
     292    }
    328293}
    329294
     
    338303
    339304    if (loadDelegate) {
    340         setUpPageLoaderClient(self, *_page);
    341         setUpResourceLoadClient(self, *_page);
     305        _page->setInjectedBundlePageLoaderClient(std::make_unique<PageLoaderClient>(self, loadDelegate));
     306        _page->setInjectedBundleResourceLoadClient(std::make_unique<ResourceLoadClient>(self, loadDelegate));
    342307    } else {
    343         WKBundlePageSetPageLoaderClient(toAPI(_page.get()), nullptr);
    344         WKBundlePageSetResourceLoadClient(toAPI(_page.get()), nullptr);
     308        _page->setInjectedBundlePageLoaderClient(nullptr);
     309        _page->setInjectedBundleResourceLoadClient(nullptr);
    345310    }
    346311}
  • trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp

    r238049 r238819  
    8282}
    8383
    84 void InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame(WebPage& page, WebFrame& frame, RefPtr<API::Object>& userData)
     84void InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame(WebPage& page, WebFrame& frame, CompletionHandler<void(RefPtr<API::Object>&&)>&& completionHandler)
    8585{
    8686    if (!m_client.didStartProvisionalLoadForFrame)
    87         return;
     87        return completionHandler(nullptr);
    8888
    8989    WKTypeRef userDataToPass = nullptr;
    9090    m_client.didStartProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), &userDataToPass, m_client.base.clientInfo);
    91     userData = adoptRef(toImpl(userDataToPass));
     91    completionHandler(adoptRef(toImpl(userDataToPass)));
    9292}
    9393
  • trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h

    r238771 r238819  
    5050    void willLoadDataRequest(WebPage&, const WebCore::ResourceRequest&, WebCore::SharedBuffer*, const WTF::String&, const WTF::String&, const URL&, API::Object*) override;
    5151
    52     void didStartProvisionalLoadForFrame(WebPage&, WebFrame&, RefPtr<API::Object>&) override;
     52    void didStartProvisionalLoadForFrame(WebPage&, WebFrame&, CompletionHandler<void(RefPtr<API::Object>&&)>&&) override;
    5353    void didReceiveServerRedirectForProvisionalLoadForFrame(WebPage&, WebFrame&, RefPtr<API::Object>&) override;
    5454    void didFailProvisionalLoadWithErrorForFrame(WebPage&, WebFrame&, const WebCore::ResourceError&, RefPtr<API::Object>&) override;
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r238787 r238819  
    458458}
    459459
    460 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
    461 {
    462     WebPage* webPage = m_frame->page();
    463     if (!webPage)
    464         return;
     460void WebFrameLoaderClient::dispatchDidStartProvisionalLoad(CompletionHandler<void()>&& completionHandler)
     461{
     462    WebPage* webPage = m_frame->page();
     463    if (!webPage)
     464        return completionHandler();
    465465
    466466#if ENABLE(FULLSCREEN_API)
     
    474474
    475475    WebDocumentLoader& provisionalLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
    476     auto& url = provisionalLoader.url();
    477     RefPtr<API::Object> userData;
    478 
    479     // Notify the bundle client.
    480     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(*webPage, *m_frame, userData);
    481 
    482     auto& unreachableURL = provisionalLoader.unreachableURL();
    483 
    484     // Notify the UIProcess.
    485     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), provisionalLoader.navigationID(), url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
     476
     477    // Notify the bundle client.
     478    webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(*webPage, *m_frame, [completionHandler = WTFMove(completionHandler), webPage = makeRef(*webPage), url = provisionalLoader.url(), unreachableURL = provisionalLoader.unreachableURL(), frameID = m_frame->frameID(), navigationID = provisionalLoader.navigationID()] (RefPtr<API::Object>&& userData) mutable {
     479        // Notify the UIProcess.
     480        webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(frameID, navigationID, url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
     481        completionHandler();
     482    });
    486483}
    487484
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h

    r238771 r238819  
    110110    void dispatchDidPopStateWithinPage() final;
    111111    void dispatchWillClose() final;
    112     void dispatchDidStartProvisionalLoad() final;
     112    void dispatchDidStartProvisionalLoad(CompletionHandler<void()>&&) final;
    113113    void dispatchDidReceiveTitle(const WebCore::StringWithDirection&) final;
    114114    void dispatchDidCommitLoad(std::optional<WebCore::HasInsecureContent>) final;
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r238815 r238819  
     12018-12-03  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler
     4        https://bugs.webkit.org/show_bug.cgi?id=192272
     5
     6        Reviewed by Brady Eidson.
     7
     8        * WebCoreSupport/WebFrameLoaderClient.h:
     9        * WebCoreSupport/WebFrameLoaderClient.mm:
     10        (WebFrameLoaderClient::dispatchDidStartProvisionalLoad):
     11
    1122018-12-03  Jer Noble  <jer.noble@apple.com>
    213
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h

    r238771 r238819  
    115115   
    116116    void dispatchWillClose() final;
    117     void dispatchDidStartProvisionalLoad() final;
     117    void dispatchDidStartProvisionalLoad(CompletionHandler<void()>&&) final;
    118118    void dispatchDidReceiveTitle(const WebCore::StringWithDirection&) final;
    119119    void dispatchDidCommitLoad(std::optional<WebCore::HasInsecureContent>) final;
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm

    r238771 r238819  
    667667}
    668668
    669 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
     669void WebFrameLoaderClient::dispatchDidStartProvisionalLoad(CompletionHandler<void()>&& completionHandler)
    670670{
    671671    ASSERT(!m_webFrame->_private->provisionalURL);
     
    684684    if (implementations->didStartProvisionalLoadForFrameFunc)
    685685        CallFrameLoadDelegate(implementations->didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
     686    completionHandler();
    686687}
    687688
  • trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp

    r238633 r238819  
    420420}
    421421
    422 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
     422void WebFrameLoaderClient::dispatchDidStartProvisionalLoad(CompletionHandler<void()>&& completionHandler)
    423423{
    424424    WebView* webView = m_webFrame->webView();
     
    426426    if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    427427        frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
     428    completionHandler();
    428429}
    429430
  • trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h

    r238774 r238819  
    9292    void dispatchDidPopStateWithinPage() override;
    9393    void dispatchWillClose() override;
    94     void dispatchDidStartProvisionalLoad() override;
     94    void dispatchDidStartProvisionalLoad(CompletionHandler<void()>&&) override;
    9595    void dispatchDidReceiveTitle(const WebCore::StringWithDirection&) override;
    9696    void dispatchDidCommitLoad(std::optional<WebCore::HasInsecureContent>) override;
  • trunk/Tools/ChangeLog

    r238795 r238819  
     12018-12-03  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler
     4        https://bugs.webkit.org/show_bug.cgi?id=192272
     5
     6        Reviewed by Brady Eidson.
     7
     8        * TestWebKitAPI/Tests/WebKitCocoa/ParserYieldTokenPlugIn.mm:
     9        (-[ParserYieldTokenPlugIn webProcessPlugInBrowserContextController:willStartProvisionalLoadForFrame:completionHandler:]):
     10        (-[ParserYieldTokenPlugIn webProcessPlugInBrowserContextController:didCommitLoadForFrame:]):
     11
    1122018-12-03  Wenson Hsieh  <wenson_hsieh@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ParserYieldTokenPlugIn.mm

    r233891 r238819  
    3838#import <wtf/RetainPtr.h>
    3939
     40static bool willStartProvisionalLoadForFrameCalled = false;
     41
    4042@interface ParserYieldTokenPlugIn : NSObject <WKWebProcessPlugIn, WKWebProcessPlugInLoadDelegate, ParserYieldTokenTestBundle>
    4143@end
     
    6567}
    6668
     69- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller willStartProvisionalLoadForFrame:(WKWebProcessPlugInFrame *)frame completionHandler:(void(^)(void))completionHandler
     70{
     71    willStartProvisionalLoadForFrameCalled = true;
     72    completionHandler();
     73}
     74
    6775- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didCommitLoadForFrame:(WKWebProcessPlugInFrame *)frame
    6876{
     77    ASSERT(willStartProvisionalLoadForFrameCalled);
     78
    6979    _loadCommitted = YES;
    7080    while (_numberOfTokensToTakeAfterComittingLoad) {
Note: See TracChangeset for help on using the changeset viewer.