Unreviewed, fix iOS build with recent SDKs.
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / WKBrowsingContextController.mm
1 /*
2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WKBrowsingContextControllerInternal.h"
28
29 #import "APIData.h"
30 #import "APINavigation.h"
31 #import "ObjCObjectGraph.h"
32 #import "PageLoadStateObserver.h"
33 #import "RemoteObjectRegistry.h"
34 #import "RemoteObjectRegistryMessages.h"
35 #import "WKBackForwardListInternal.h"
36 #import "WKBackForwardListItemInternal.h"
37 #import "WKBrowsingContextGroupInternal.h"
38 #import "WKBrowsingContextHandleInternal.h"
39 #import "WKBrowsingContextLoadDelegatePrivate.h"
40 #import "WKBrowsingContextPolicyDelegate.h"
41 #import "WKFrame.h"
42 #import "WKFramePolicyListener.h"
43 #import "WKNSArray.h"
44 #import "WKNSData.h"
45 #import "WKNSError.h"
46 #import "WKNSURLAuthenticationChallenge.h"
47 #import "WKNSURLExtras.h"
48 #import "WKPagePolicyClientInternal.h"
49 #import "WKProcessGroupPrivate.h"
50 #import "WKRetainPtr.h"
51 #import "WKURLRequestNS.h"
52 #import "WKURLResponseNS.h"
53 #import "WKViewInternal.h"
54 #import "WebCertificateInfo.h"
55 #import "WebPageProxy.h"
56 #import "WebProcessPool.h"
57 #import "WebProtectionSpace.h"
58 #import "_WKRemoteObjectRegistryInternal.h"
59 #import <wtf/NeverDestroyed.h>
60 #import <wtf/WeakObjCPtr.h>
61
62 NSString * const WKActionIsMainFrameKey = @"WKActionIsMainFrameKey";
63 NSString * const WKActionNavigationTypeKey = @"WKActionNavigationTypeKey";
64 NSString * const WKActionMouseButtonKey = @"WKActionMouseButtonKey";
65 NSString * const WKActionModifierFlagsKey = @"WKActionModifierFlagsKey";
66 NSString * const WKActionOriginalURLRequestKey = @"WKActionOriginalURLRequestKey";
67 NSString * const WKActionURLRequestKey = @"WKActionURLRequestKey";
68 NSString * const WKActionURLResponseKey = @"WKActionURLResponseKey";
69 NSString * const WKActionFrameNameKey = @"WKActionFrameNameKey";
70 NSString * const WKActionOriginatingFrameURLKey = @"WKActionOriginatingFrameURLKey";
71 NSString * const WKActionCanShowMIMETypeKey = @"WKActionCanShowMIMETypeKey";
72
73 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
74 @implementation WKBrowsingContextController {
75 IGNORE_WARNINGS_END
76     RefPtr<WebKit::WebPageProxy> _page;
77     std::unique_ptr<WebKit::PageLoadStateObserver> _pageLoadStateObserver;
78
79     WeakObjCPtr<id <WKBrowsingContextLoadDelegate>> _loadDelegate;
80     WeakObjCPtr<id <WKBrowsingContextPolicyDelegate>> _policyDelegate;
81 }
82
83 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
84 static HashMap<WebKit::WebPageProxy*, __unsafe_unretained WKBrowsingContextController *>& browsingContextControllerMap()
85 {
86     static NeverDestroyed<HashMap<WebKit::WebPageProxy*, __unsafe_unretained WKBrowsingContextController *>> browsingContextControllerMap;
87     return browsingContextControllerMap;
88 }
89 ALLOW_DEPRECATED_DECLARATIONS_END
90
91 - (void)dealloc
92 {
93     ASSERT(browsingContextControllerMap().get(_page.get()) == self);
94     browsingContextControllerMap().remove(_page.get());
95
96     _page->pageLoadState().removeObserver(*_pageLoadStateObserver);
97
98     [super dealloc];
99 }
100
101 #pragma mark Loading
102
103 + (void)registerSchemeForCustomProtocol:(NSString *)scheme
104 {
105     WebKit::WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(scheme);
106 }
107
108 + (void)unregisterSchemeForCustomProtocol:(NSString *)scheme
109 {
110     WebKit::WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(scheme);
111 }
112
113 - (void)loadRequest:(NSURLRequest *)request
114 {
115     [self loadRequest:request userData:nil];
116 }
117
118 - (void)loadRequest:(NSURLRequest *)request userData:(id)userData
119 {
120     RefPtr<WebKit::ObjCObjectGraph> wkUserData;
121     if (userData)
122         wkUserData = WebKit::ObjCObjectGraph::create(userData);
123
124     _page->loadRequest(request, WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow, wkUserData.get());
125 }
126
127 - (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory
128 {
129     [self loadFileURL:URL restrictToFilesWithin:allowedDirectory userData:nil];
130 }
131
132 - (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory userData:(id)userData
133 {
134     if (![URL isFileURL] || (allowedDirectory && ![allowedDirectory isFileURL]))
135         [NSException raise:NSInvalidArgumentException format:@"Attempted to load a non-file URL"];
136
137     RefPtr<WebKit::ObjCObjectGraph> wkUserData;
138     if (userData)
139         wkUserData = WebKit::ObjCObjectGraph::create(userData);
140
141     _page->loadFile([URL _web_originalDataAsWTFString], [allowedDirectory _web_originalDataAsWTFString], wkUserData.get());
142 }
143
144 - (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL
145 {
146     [self loadHTMLString:HTMLString baseURL:baseURL userData:nil];
147 }
148
149 - (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL userData:(id)userData
150 {
151     RefPtr<WebKit::ObjCObjectGraph> wkUserData;
152     if (userData)
153         wkUserData = WebKit::ObjCObjectGraph::create(userData);
154
155     NSData *data = [HTMLString dataUsingEncoding:NSUTF8StringEncoding];
156     _page->loadData({ static_cast<const uint8_t*>(data.bytes), data.length }, "text/html"_s, "UTF-8"_s, [baseURL _web_originalDataAsWTFString], wkUserData.get());
157 }
158
159 - (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)baseURL forUnreachableURL:(NSURL *)unreachableURL
160 {
161     NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
162     _page->loadAlternateHTML({ static_cast<const uint8_t*>(data.bytes), data.length }, "UTF-8"_s, baseURL, unreachableURL);
163 }
164
165 - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
166 {
167     [self loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL userData:nil];
168 }
169
170 - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL userData:(id)userData
171 {
172     RefPtr<WebKit::ObjCObjectGraph> wkUserData;
173     if (userData)
174         wkUserData = WebKit::ObjCObjectGraph::create(userData);
175
176     _page->loadData({ static_cast<const uint8_t*>(data.bytes), data.length }, MIMEType, encodingName, [baseURL _web_originalDataAsWTFString], wkUserData.get());
177 }
178
179 - (void)stopLoading
180 {
181     _page->stopLoading();
182 }
183
184 - (void)reload
185 {
186     _page->reload({ });
187 }
188
189 - (void)reloadFromOrigin
190 {
191     _page->reload(WebCore::ReloadOption::FromOrigin);
192 }
193
194 - (NSString *)applicationNameForUserAgent
195 {
196     const String& applicationName = _page->applicationNameForUserAgent();
197     return !applicationName ? nil : (NSString *)applicationName;
198 }
199
200 - (void)setApplicationNameForUserAgent:(NSString *)applicationNameForUserAgent
201 {
202     _page->setApplicationNameForUserAgent(applicationNameForUserAgent);
203 }
204
205 - (NSString *)customUserAgent
206 {
207     const String& customUserAgent = _page->customUserAgent();
208     return !customUserAgent ? nil : (NSString *)customUserAgent;
209 }
210
211 - (void)setCustomUserAgent:(NSString *)customUserAgent
212 {
213     _page->setCustomUserAgent(customUserAgent);
214 }
215
216 #pragma mark Back/Forward
217
218 - (void)goForward
219 {
220     _page->goForward();
221 }
222
223 - (BOOL)canGoForward
224 {
225     return !!_page->backForwardList().forwardItem();
226 }
227
228 - (void)goBack
229 {
230     _page->goBack();
231 }
232
233 - (BOOL)canGoBack
234 {
235     return !!_page->backForwardList().backItem();
236 }
237
238 - (void)goToBackForwardListItem:(WKBackForwardListItem *)item
239 {
240     _page->goToBackForwardItem(item._item);
241 }
242
243 - (WKBackForwardList *)backForwardList
244 {
245     return wrapper(_page->backForwardList());
246 }
247
248 #pragma mark Active Load Introspection
249
250 - (BOOL)isLoading
251 {
252     return _page->pageLoadState().isLoading();
253 }
254
255 - (NSURL *)activeURL
256 {
257     return [NSURL _web_URLWithWTFString:_page->pageLoadState().activeURL()];
258 }
259
260 - (NSURL *)provisionalURL
261 {
262     return [NSURL _web_URLWithWTFString:_page->pageLoadState().provisionalURL()];
263 }
264
265 - (NSURL *)committedURL
266 {
267     return [NSURL _web_URLWithWTFString:_page->pageLoadState().url()];
268 }
269
270 - (NSURL *)unreachableURL
271 {
272     return [NSURL _web_URLWithWTFString:_page->pageLoadState().unreachableURL()];
273 }
274
275 - (BOOL)hasOnlySecureContent
276 {
277     return _page->pageLoadState().hasOnlySecureContent();
278 }
279
280 - (double)estimatedProgress
281 {
282     return _page->estimatedProgress();
283 }
284
285 #pragma mark Active Document Introspection
286
287 - (NSString *)title
288 {
289     return _page->pageLoadState().title();
290 }
291
292 - (NSArray *)certificateChain
293 {
294     if (WebKit::WebFrameProxy* mainFrame = _page->mainFrame())
295         return mainFrame->certificateInfo() ? (__bridge NSArray *)mainFrame->certificateInfo()->certificateInfo().certificateChain() : nil;
296
297     return nil;
298 }
299
300 #pragma mark Zoom
301
302 - (CGFloat)textZoom
303 {
304     return _page->textZoomFactor();
305 }
306
307 - (void)setTextZoom:(CGFloat)textZoom
308 {
309     _page->setTextZoomFactor(textZoom);
310 }
311
312 - (CGFloat)pageZoom
313 {
314     return _page->pageZoomFactor();
315 }
316
317 - (void)setPageZoom:(CGFloat)pageZoom
318 {
319     _page->setPageZoomFactor(pageZoom);
320 }
321
322 static void didStartProvisionalNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
323 {
324     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
325     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
326     ALLOW_DEPRECATED_DECLARATIONS_END
327     auto loadDelegate = browsingContext->_loadDelegate.get();
328
329     if ([loadDelegate respondsToSelector:@selector(browsingContextControllerDidStartProvisionalLoad:)])
330         [loadDelegate browsingContextControllerDidStartProvisionalLoad:browsingContext];
331 }
332
333 static void didReceiveServerRedirectForProvisionalNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
334 {
335     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
336     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
337     ALLOW_DEPRECATED_DECLARATIONS_END
338     auto loadDelegate = browsingContext->_loadDelegate.get();
339
340     if ([loadDelegate respondsToSelector:@selector(browsingContextControllerDidReceiveServerRedirectForProvisionalLoad:)])
341         [loadDelegate browsingContextControllerDidReceiveServerRedirectForProvisionalLoad:browsingContext];
342 }
343
344 static void didFailProvisionalNavigation(WKPageRef page, WKNavigationRef, WKErrorRef error, WKTypeRef userData, const void* clientInfo)
345 {
346     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
347     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
348     ALLOW_DEPRECATED_DECLARATIONS_END
349     auto loadDelegate = browsingContext->_loadDelegate.get();
350
351     if ([loadDelegate respondsToSelector:@selector(browsingContextController:didFailProvisionalLoadWithError:)])
352         [loadDelegate browsingContextController:browsingContext didFailProvisionalLoadWithError:wrapper(*WebKit::toImpl(error))];
353 }
354
355 static void didCommitNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
356 {
357     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
358     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
359     ALLOW_DEPRECATED_DECLARATIONS_END
360     auto loadDelegate = browsingContext->_loadDelegate.get();
361
362     if ([loadDelegate respondsToSelector:@selector(browsingContextControllerDidCommitLoad:)])
363         [loadDelegate browsingContextControllerDidCommitLoad:browsingContext];
364 }
365
366 static void didFinishNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
367 {
368     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
369     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
370     ALLOW_DEPRECATED_DECLARATIONS_END
371     auto loadDelegate = browsingContext->_loadDelegate.get();
372
373     if ([loadDelegate respondsToSelector:@selector(browsingContextControllerDidFinishLoad:)])
374         [loadDelegate browsingContextControllerDidFinishLoad:browsingContext];
375 }
376
377 static void didFailNavigation(WKPageRef page, WKNavigationRef, WKErrorRef error, WKTypeRef userData, const void* clientInfo)
378 {
379     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
380     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
381     ALLOW_DEPRECATED_DECLARATIONS_END
382     auto loadDelegate = browsingContext->_loadDelegate.get();
383
384     if ([loadDelegate respondsToSelector:@selector(browsingContextController:didFailLoadWithError:)])
385         [loadDelegate browsingContextController:browsingContext didFailLoadWithError:wrapper(*WebKit::toImpl(error))];
386 }
387
388 static bool canAuthenticateAgainstProtectionSpace(WKPageRef page, WKProtectionSpaceRef protectionSpace, const void *clientInfo)
389 {
390     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
391     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
392     ALLOW_DEPRECATED_DECLARATIONS_END
393     auto loadDelegate = browsingContext->_loadDelegate.get();
394
395     if ([loadDelegate respondsToSelector:@selector(browsingContextController:canAuthenticateAgainstProtectionSpace:)])
396         return [(id <WKBrowsingContextLoadDelegatePrivate>)loadDelegate browsingContextController:browsingContext canAuthenticateAgainstProtectionSpace:WebKit::toImpl(protectionSpace)->protectionSpace().nsSpace()];
397
398     return false;
399 }
400
401 static void didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo)
402 {
403     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
404     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
405     ALLOW_DEPRECATED_DECLARATIONS_END
406     auto loadDelegate = browsingContext->_loadDelegate.get();
407
408     if ([loadDelegate respondsToSelector:@selector(browsingContextController:didReceiveAuthenticationChallenge:)])
409         [(id <WKBrowsingContextLoadDelegatePrivate>)loadDelegate browsingContextController:browsingContext didReceiveAuthenticationChallenge:wrapper(*WebKit::toImpl(authenticationChallenge))];
410 }
411
412 static void processDidCrash(WKPageRef page, const void* clientInfo)
413 {
414     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
415     auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
416     ALLOW_DEPRECATED_DECLARATIONS_END
417     auto loadDelegate = browsingContext->_loadDelegate.get();
418
419     if ([loadDelegate respondsToSelector:@selector(browsingContextControllerWebProcessDidCrash:)])
420         [(id <WKBrowsingContextLoadDelegatePrivate>)loadDelegate browsingContextControllerWebProcessDidCrash:browsingContext];
421 }
422
423 static void setUpPageLoaderClient(WKBrowsingContextController *browsingContext, WebKit::WebPageProxy& page)
424 {
425     WKPageNavigationClientV0 loaderClient;
426     memset(&loaderClient, 0, sizeof(loaderClient));
427
428     loaderClient.base.version = 0;
429     loaderClient.base.clientInfo = (__bridge void*)browsingContext;
430     loaderClient.didStartProvisionalNavigation = didStartProvisionalNavigation;
431     loaderClient.didReceiveServerRedirectForProvisionalNavigation = didReceiveServerRedirectForProvisionalNavigation;
432     loaderClient.didFailProvisionalNavigation = didFailProvisionalNavigation;
433     loaderClient.didCommitNavigation = didCommitNavigation;
434     loaderClient.didFinishNavigation = didFinishNavigation;
435     loaderClient.didFailNavigation = didFailNavigation;
436     loaderClient.canAuthenticateAgainstProtectionSpace = canAuthenticateAgainstProtectionSpace;
437     loaderClient.didReceiveAuthenticationChallenge = didReceiveAuthenticationChallenge;
438     loaderClient.webProcessDidCrash = processDidCrash;
439
440     WKPageSetPageNavigationClient(toAPI(&page), &loaderClient.base);
441 }
442
443 static WKPolicyDecisionHandler makePolicyDecisionBlock(WKFramePolicyListenerRef listener)
444 {
445     WKRetain(listener); // Released in the decision handler below.
446
447     return [[^(WKPolicyDecision decision) {
448         switch (decision) {
449         case WKPolicyDecisionCancel:
450             WKFramePolicyListenerIgnore(listener);                    
451             break;
452         
453         case WKPolicyDecisionAllow:
454             WKFramePolicyListenerUse(listener);
455             break;
456         
457         case WKPolicyDecisionBecomeDownload:
458             WKFramePolicyListenerDownload(listener);
459             break;
460         };
461
462         WKRelease(listener); // Retained in the context above.
463     } copy] autorelease];
464 }
465
466 static void setUpPagePolicyClient(WKBrowsingContextController *browsingContext, WebKit::WebPageProxy& page)
467 {
468     WKPagePolicyClientInternal policyClient;
469     memset(&policyClient, 0, sizeof(policyClient));
470
471     policyClient.base.version = 2;
472     policyClient.base.clientInfo = (__bridge void*)browsingContext;
473
474     policyClient.decidePolicyForNavigationAction = [](WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKFrameRef originatingFrame, WKURLRequestRef originalRequest, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
475     {
476         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
477         auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
478         ALLOW_DEPRECATED_DECLARATIONS_END
479         auto policyDelegate = browsingContext->_policyDelegate.get();
480
481         if ([policyDelegate respondsToSelector:@selector(browsingContextController:decidePolicyForNavigationAction:decisionHandler:)]) {
482             NSDictionary *actionDictionary = @{
483                 WKActionIsMainFrameKey: @(WKFrameIsMainFrame(frame)),
484                 WKActionNavigationTypeKey: @(navigationType),
485                 WKActionModifierFlagsKey: @(modifiers),
486                 WKActionMouseButtonKey: @(mouseButton),
487                 WKActionOriginalURLRequestKey: adoptNS(WKURLRequestCopyNSURLRequest(originalRequest)).get(),
488                 WKActionURLRequestKey: adoptNS(WKURLRequestCopyNSURLRequest(request)).get()
489             };
490
491             if (originatingFrame) {
492                 actionDictionary = [[actionDictionary mutableCopy] autorelease];
493                 [(NSMutableDictionary *)actionDictionary setObject:[NSURL _web_URLWithWTFString:WebKit::toImpl(originatingFrame)->url()] forKey:WKActionOriginatingFrameURLKey];
494             }
495             
496             [policyDelegate browsingContextController:browsingContext decidePolicyForNavigationAction:actionDictionary decisionHandler:makePolicyDecisionBlock(listener)];
497         } else
498             WKFramePolicyListenerUse(listener);
499     };
500
501     policyClient.decidePolicyForNewWindowAction = [](WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
502     {
503         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
504         auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
505         ALLOW_DEPRECATED_DECLARATIONS_END
506         auto policyDelegate = browsingContext->_policyDelegate.get();
507
508         if ([policyDelegate respondsToSelector:@selector(browsingContextController:decidePolicyForNewWindowAction:decisionHandler:)]) {
509             NSDictionary *actionDictionary = @{
510                 WKActionIsMainFrameKey: @(WKFrameIsMainFrame(frame)),
511                 WKActionNavigationTypeKey: @(navigationType),
512                 WKActionModifierFlagsKey: @(modifiers),
513                 WKActionMouseButtonKey: @(mouseButton),
514                 WKActionURLRequestKey: adoptNS(WKURLRequestCopyNSURLRequest(request)).get(),
515                 WKActionFrameNameKey: WebKit::toImpl(frameName)->wrapper()
516             };
517             
518             [policyDelegate browsingContextController:browsingContext decidePolicyForNewWindowAction:actionDictionary decisionHandler:makePolicyDecisionBlock(listener)];
519         } else
520             WKFramePolicyListenerUse(listener);
521     };
522
523     policyClient.decidePolicyForResponse = [](WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, bool canShowMIMEType, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
524     {
525         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
526         auto browsingContext = (__bridge WKBrowsingContextController *)clientInfo;
527         ALLOW_DEPRECATED_DECLARATIONS_END
528         auto policyDelegate = browsingContext->_policyDelegate.get();
529
530         if ([policyDelegate respondsToSelector:@selector(browsingContextController:decidePolicyForResponseAction:decisionHandler:)]) {
531             NSDictionary *actionDictionary = @{
532                 WKActionIsMainFrameKey: @(WKFrameIsMainFrame(frame)),
533                 WKActionURLRequestKey: adoptNS(WKURLRequestCopyNSURLRequest(request)).get(),
534                 WKActionURLResponseKey: adoptNS(WKURLResponseCopyNSURLResponse(response)).get(),
535                 WKActionCanShowMIMETypeKey: @(canShowMIMEType),
536             };
537
538             [policyDelegate browsingContextController:browsingContext decidePolicyForResponseAction:actionDictionary decisionHandler:makePolicyDecisionBlock(listener)];
539         } else
540             WKFramePolicyListenerUse(listener);
541     };
542
543     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
544     WKPageSetPagePolicyClient(toAPI(&page), &policyClient.base);
545     ALLOW_DEPRECATED_DECLARATIONS_END
546 }
547
548 - (id <WKBrowsingContextLoadDelegate>)loadDelegate
549 {
550     return _loadDelegate.getAutoreleased();
551 }
552
553 - (void)setLoadDelegate:(id <WKBrowsingContextLoadDelegate>)loadDelegate
554 {
555     _loadDelegate = loadDelegate;
556
557     if (loadDelegate)
558         setUpPageLoaderClient(self, *_page);
559     else
560         WKPageSetPageNavigationClient(toAPI(_page.get()), nullptr);
561 }
562
563 - (id <WKBrowsingContextPolicyDelegate>)policyDelegate
564 {
565     return _policyDelegate.getAutoreleased();
566 }
567
568 - (void)setPolicyDelegate:(id <WKBrowsingContextPolicyDelegate>)policyDelegate
569 {
570     _policyDelegate = policyDelegate;
571
572     if (policyDelegate)
573         setUpPagePolicyClient(self, *_page);
574     else {
575         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
576         WKPageSetPagePolicyClient(toAPI(_page.get()), nullptr);
577         ALLOW_DEPRECATED_DECLARATIONS_END
578     }
579 }
580
581 - (id <WKBrowsingContextHistoryDelegate>)historyDelegate
582 {
583     return _historyDelegate.getAutoreleased();
584 }
585
586 - (void)setHistoryDelegate:(id <WKBrowsingContextHistoryDelegate>)historyDelegate
587 {
588     _historyDelegate = historyDelegate;
589 }
590
591 + (NSMutableSet *)customSchemes
592 {
593     static NSMutableSet *customSchemes = [[NSMutableSet alloc] init];
594     return customSchemes;
595 }
596
597 - (instancetype)_initWithPageRef:(WKPageRef)pageRef
598 {
599     if (!(self = [super init]))
600         return nil;
601
602     _page = WebKit::toImpl(pageRef);
603
604     _pageLoadStateObserver = std::make_unique<WebKit::PageLoadStateObserver>(self);
605     _page->pageLoadState().addObserver(*_pageLoadStateObserver);
606
607     ASSERT(!browsingContextControllerMap().contains(_page.get()));
608     browsingContextControllerMap().set(_page.get(), self);
609
610     return self;
611 }
612
613 + (WKBrowsingContextController *)_browsingContextControllerForPageRef:(WKPageRef)pageRef
614 {
615     return browsingContextControllerMap().get(WebKit::toImpl(pageRef));
616 }
617
618 @end
619
620 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
621 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
622 @implementation WKBrowsingContextController (Private)
623 IGNORE_WARNINGS_END
624
625 - (WKPageRef)_pageRef
626 {
627     return WebKit::toAPI(_page.get());
628 }
629
630 - (void)setPaginationMode:(WKBrowsingContextPaginationMode)paginationMode
631 {
632     WebCore::Pagination::Mode mode;
633     switch (paginationMode) {
634     case WKPaginationModeUnpaginated:
635         mode = WebCore::Pagination::Unpaginated;
636         break;
637     case WKPaginationModeLeftToRight:
638         mode = WebCore::Pagination::LeftToRightPaginated;
639         break;
640     case WKPaginationModeRightToLeft:
641         mode = WebCore::Pagination::RightToLeftPaginated;
642         break;
643     case WKPaginationModeTopToBottom:
644         mode = WebCore::Pagination::TopToBottomPaginated;
645         break;
646     case WKPaginationModeBottomToTop:
647         mode = WebCore::Pagination::BottomToTopPaginated;
648         break;
649     default:
650         return;
651     }
652
653     _page->setPaginationMode(mode);
654 }
655
656 - (WKBrowsingContextPaginationMode)paginationMode
657 {
658     switch (_page->paginationMode()) {
659     case WebCore::Pagination::Unpaginated:
660         return WKPaginationModeUnpaginated;
661     case WebCore::Pagination::LeftToRightPaginated:
662         return WKPaginationModeLeftToRight;
663     case WebCore::Pagination::RightToLeftPaginated:
664         return WKPaginationModeRightToLeft;
665     case WebCore::Pagination::TopToBottomPaginated:
666         return WKPaginationModeTopToBottom;
667     case WebCore::Pagination::BottomToTopPaginated:
668         return WKPaginationModeBottomToTop;
669     }
670
671     ASSERT_NOT_REACHED();
672     return WKPaginationModeUnpaginated;
673 }
674
675 - (void)setPaginationBehavesLikeColumns:(BOOL)behavesLikeColumns
676 {
677     _page->setPaginationBehavesLikeColumns(behavesLikeColumns);
678 }
679
680 - (BOOL)paginationBehavesLikeColumns
681 {
682     return _page->paginationBehavesLikeColumns();
683 }
684
685 - (void)setPageLength:(CGFloat)pageLength
686 {
687     _page->setPageLength(pageLength);
688 }
689
690 - (CGFloat)pageLength
691 {
692     return _page->pageLength();
693 }
694
695 - (void)setGapBetweenPages:(CGFloat)gapBetweenPages
696 {
697     _page->setGapBetweenPages(gapBetweenPages);
698 }
699
700 - (CGFloat)gapBetweenPages
701 {
702     return _page->gapBetweenPages();
703 }
704
705 - (void)setPaginationLineGridEnabled:(BOOL)lineGridEnabled
706 {
707     _page->setPaginationLineGridEnabled(lineGridEnabled);
708 }
709
710 - (BOOL)paginationLineGridEnabled
711 {
712     return _page->paginationLineGridEnabled();
713 }
714
715 - (NSUInteger)pageCount
716 {
717     return _page->pageCount();
718 }
719
720 - (WKBrowsingContextHandle *)handle
721 {
722     return [[[WKBrowsingContextHandle alloc] _initWithPageID:_page->pageID()] autorelease];
723 }
724
725 - (_WKRemoteObjectRegistry *)_remoteObjectRegistry
726 {
727 #if PLATFORM(MAC)
728     return _page->remoteObjectRegistry();
729 #else
730     return nil;
731 #endif
732 }
733
734 - (pid_t)processIdentifier
735 {
736     return _page->processIdentifier();
737 }
738
739 - (BOOL)_webProcessIsResponsive
740 {
741     return _page->process().isResponsive();
742 }
743
744 @end
745 ALLOW_DEPRECATED_DECLARATIONS_END