2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #import "WebFrameLoaderClient.h"
31 // Terrible hack; lets us get at the WebFrame private structure.
32 #define private public
36 #import "DOMElementInternal.h"
37 #import "WebBackForwardList.h"
38 #import "WebChromeClient.h"
39 #import "WebDataSourceInternal.h"
40 #import "WebPolicyDelegatePrivate.h"
41 #import "WebDefaultResourceLoadDelegate.h"
42 #import "WebDocumentInternal.h"
43 #import "WebDocumentLoaderMac.h"
44 #import "WebDownloadInternal.h"
45 #import "WebElementDictionary.h"
46 #import "WebFormDelegate.h"
47 #import "WebFrameBridge.h"
48 #import "WebFrameInternal.h"
49 #import "WebFrameLoadDelegate.h"
50 #import "WebFrameViewInternal.h"
51 #import "WebHTMLRepresentation.h"
52 #import "WebHTMLView.h"
53 #import "WebHistoryItemInternal.h"
54 #import "WebHistoryItemPrivate.h"
55 #import "WebHistoryPrivate.h"
56 #import "WebIconDatabaseInternal.h"
57 #import "WebKitErrorsPrivate.h"
58 #import "WebKitNSStringExtras.h"
59 #import "WebNSURLExtras.h"
60 #import "WebPanelAuthenticationHandler.h"
61 #import "WebPolicyDelegate.h"
62 #import "WebPreferences.h"
63 #import "WebResourceLoadDelegate.h"
64 #import "WebResourcePrivate.h"
65 #import "WebScriptDebugServerPrivate.h"
66 #import "WebUIDelegate.h"
67 #import "WebViewInternal.h"
68 #import <WebCore/AuthenticationMac.h>
69 #import <WebCore/BlockExceptions.h>
70 #import <WebCore/Chrome.h>
71 #import <WebCore/Document.h>
72 #import <WebCore/DocumentLoader.h>
73 #import <WebCore/EventHandler.h>
74 #import <WebCore/FormState.h>
75 #import <WebCore/FrameLoader.h>
76 #import <WebCore/FrameLoaderTypes.h>
77 #import <WebCore/FrameMac.h>
78 #import <WebCore/FrameTree.h>
79 #import <WebCore/HistoryItem.h>
80 #import <WebCore/HitTestResult.h>
81 #import <WebCore/HTMLFormElement.h>
82 #import <WebCore/IconDatabase.h>
83 #import <WebCore/LoaderNSURLExtras.h>
84 #import <WebCore/MouseEvent.h>
85 #import <WebCore/Page.h>
86 #import <WebCore/PageCache.h>
87 #import <WebCore/PageState.h>
88 #import <WebCore/PlatformString.h>
89 #import <WebCore/ResourceError.h>
90 #import <WebCore/ResourceHandle.h>
91 #import <WebCore/ResourceLoader.h>
92 #import <WebCore/ResourceRequest.h>
93 #import <WebCore/WebCoreFrameBridge.h>
94 #import <WebCore/WebDataProtocol.h>
95 #import <WebCore/Widget.h>
96 #import <WebKit/DOMElement.h>
97 #import <WebKit/DOMHTMLFormElement.h>
98 #import <WebKitSystemInterface.h>
99 #import <wtf/PassRefPtr.h>
101 using namespace WebCore;
103 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener>
107 - (id)initWithWebCoreFrame:(Frame*)frame;
111 static inline WebView *getWebView(DocumentLoader* loader)
113 return kit(loader->frameLoader()->frame()->page());
116 static inline WebDataSource *dataSource(DocumentLoader* loader)
118 return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
121 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
122 : m_webFrame(webFrame)
123 , m_policyFunction(0)
124 , m_archivedResourcesDeliveryTimer(this, &WebFrameLoaderClient::deliverArchivedResources)
128 void WebFrameLoaderClient::frameLoaderDestroyed()
133 bool WebFrameLoaderClient::hasWebView() const
135 return [m_webFrame.get() webView] != nil;
138 bool WebFrameLoaderClient::hasFrameView() const
140 return m_webFrame->_private->webFrameView != nil;
143 bool WebFrameLoaderClient::privateBrowsingEnabled() const
145 return [[getWebView(m_webFrame.get()) preferences] privateBrowsingEnabled];
148 void WebFrameLoaderClient::makeDocumentView()
150 WebFrameView *v = m_webFrame->_private->webFrameView;
151 WebDataSource *ds = [m_webFrame.get() dataSource];
153 NSView <WebDocumentView> *documentView = [v _makeDocumentViewForDataSource:ds];
157 WebFrameBridge *bridge = m_webFrame->_private->bridge;
159 // FIXME: We could save work and not do this for a top-level view that is not a WebHTMLView.
160 [bridge createFrameViewWithNSView:documentView marginWidth:[v _marginWidth] marginHeight:[v _marginHeight]];
161 [m_webFrame.get() _updateBackground];
162 [bridge installInFrame:[v _scrollView]];
164 // Call setDataSource on the document view after it has been placed in the view hierarchy.
165 // This what we for the top-level view, so should do this for views in subframes as well.
166 [documentView setDataSource:ds];
169 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
171 [dataSource(loader) _makeRepresentation];
174 void WebFrameLoaderClient::setDocumentViewFromPageCache(PageCache* pageCache)
176 DocumentLoader* cachedDocumentLoader = pageCache->documentLoader();
177 ASSERT(cachedDocumentLoader);
178 NSView <WebDocumentView> *cachedView = pageCache->documentView();
179 ASSERT(cachedView != nil);
180 [cachedView setDataSource:dataSource(cachedDocumentLoader)];
181 [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
184 void WebFrameLoaderClient::forceLayout()
186 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
187 if ([view isKindOfClass:[WebHTMLView class]])
188 [(WebHTMLView *)view setNeedsToApplyStyles:YES];
189 [view setNeedsLayout:YES];
193 void WebFrameLoaderClient::forceLayoutForNonHTML()
195 WebFrameView *thisView = m_webFrame->_private->webFrameView;
196 NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
197 ASSERT(thisDocumentView != nil);
199 // Tell the just loaded document to layout. This may be necessary
200 // for non-html content that needs a layout message.
201 if (!([[m_webFrame.get() dataSource] _isDocumentHTML])) {
202 [thisDocumentView setNeedsLayout:YES];
203 [thisDocumentView layout];
204 [thisDocumentView setNeedsDisplay:YES];
208 void WebFrameLoaderClient::setCopiesOnScroll()
210 [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
213 void WebFrameLoaderClient::detachedFromParent2()
215 [m_webFrame->_private->inspectors makeObjectsPerformSelector:@selector(_webFrameDetached:) withObject:m_webFrame.get()];
216 [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
219 void WebFrameLoaderClient::detachedFromParent3()
221 [m_webFrame->_private->webFrameView release];
222 m_webFrame->_private->webFrameView = nil;
225 void WebFrameLoaderClient::detachedFromParent4()
227 m_webFrame->_private->bridge = nil;
230 void WebFrameLoaderClient::loadedFromPageCache()
232 // Release the resources kept in the page cache.
233 // They will be reset when we leave this page.
234 // The WebCore side of the page cache will have already been invalidated by
235 // the bridge to prevent premature release.
236 core(m_webFrame.get())->loader()->currentHistoryItem()->setHasPageCache(false);
239 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
241 id proxy = handle->releaseProxy();
243 [WebDownload _downloadWithLoadingConnection:handle->connection()
244 request:request.nsURLRequest()
245 response:response.nsURLResponse()
246 delegate:[getWebView(m_webFrame.get()) downloadDelegate]
250 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
252 WebView *webView = getWebView(loader);
253 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
254 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
256 if (!implementations.delegateImplementsDidLoadResourceFromMemoryCache)
259 implementations.didLoadResourceFromMemoryCacheFunc(resourceLoadDelegate, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), webView, request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
263 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
265 WebView *webView = getWebView(loader);
266 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
267 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
270 BOOL shouldRelease = NO;
271 if (implementations.delegateImplementsIdentifierForRequest)
272 object = implementations.identifierForRequestFunc(resourceLoadDelegate, @selector(webView:identifierForInitialRequest:fromDataSource:), webView, request.nsURLRequest(), dataSource(loader));
274 object = [[NSObject alloc] init];
277 [webView _addObject:object forIdentifier:identifier];
282 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
284 WebView *webView = getWebView(loader);
285 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
286 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
288 if (implementations.delegateImplementsWillSendRequest)
289 request = implementations.willSendRequestFunc(resourceLoadDelegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), webView, [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
292 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
294 WebView *webView = getWebView(m_webFrame.get());
295 id resourceLoadDelegate = [webView resourceLoadDelegate];
296 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
298 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
300 if (implementations.delegateImplementsDidReceiveAuthenticationChallenge) {
301 [resourceLoadDelegate webView:webView resource:[webView _objectForIdentifier:identifier] didReceiveAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
305 NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
306 [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
309 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
311 WebView *webView = getWebView(m_webFrame.get());
312 id resourceLoadDelegate = [webView resourceLoadDelegate];
313 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
315 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
317 if (implementations.delegateImplementsDidCancelAuthenticationChallenge) {
318 [resourceLoadDelegate webView:webView resource:[webView _objectForIdentifier:identifier] didCancelAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
322 [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
325 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
327 WebView *webView = getWebView(loader);
328 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
329 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
331 if (implementations.delegateImplementsDidReceiveResponse)
332 implementations.didReceiveResponseFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveResponse:fromDataSource:), webView, [webView _objectForIdentifier:identifier], response.nsURLResponse(), dataSource(loader));
335 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int lengthReceived)
337 WebView *webView = getWebView(loader);
338 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
339 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
341 if (implementations.delegateImplementsDidReceiveContentLength)
342 implementations.didReceiveContentLengthFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveContentLength:fromDataSource:), webView, [webView _objectForIdentifier:identifier], (WebNSUInteger)lengthReceived, dataSource(loader));
345 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
347 WebView *webView = getWebView(loader);
348 id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
349 WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
351 if (implementations.delegateImplementsDidFinishLoadingFromDataSource)
352 implementations.didFinishLoadingFromDataSourceFunc(resourceLoadDelegate, @selector(webView:resource:didFinishLoadingFromDataSource:), webView, [webView _objectForIdentifier:identifier], dataSource(loader));
353 [webView _removeObjectForIdentifier:identifier];
356 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
358 WebView *webView = getWebView(m_webFrame.get());
359 [[webView _resourceLoadDelegateForwarder] webView:webView resource:[webView _objectForIdentifier:identifier] didFailLoadingWithError:error fromDataSource:dataSource(loader)];
360 [webView _removeObjectForIdentifier:identifier];
363 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
365 WebView *webView = getWebView(m_webFrame.get());
366 [[webView _frameLoadDelegateForwarder] webView:webView didHandleOnloadEventsForFrame:m_webFrame.get()];
369 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
371 WebView *webView = getWebView(m_webFrame.get());
372 [[webView _frameLoadDelegateForwarder] webView:webView
373 didReceiveServerRedirectForProvisionalLoadForFrame:m_webFrame.get()];
376 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
378 WebView *webView = getWebView(m_webFrame.get());
379 [[webView _frameLoadDelegateForwarder] webView:webView didCancelClientRedirectForFrame:m_webFrame.get()];
382 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& URL, double delay, double fireDate)
384 WebView *webView = getWebView(m_webFrame.get());
385 [[webView _frameLoadDelegateForwarder] webView:webView
386 willPerformClientRedirectToURL:URL.getNSURL()
388 fireDate:[NSDate dateWithTimeIntervalSince1970:fireDate]
389 forFrame:m_webFrame.get()];
392 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
394 WebView *webView = getWebView(m_webFrame.get());
395 [[webView _frameLoadDelegateForwarder] webView:webView didChangeLocationWithinPageForFrame:m_webFrame.get()];
398 void WebFrameLoaderClient::dispatchWillClose()
400 WebView *webView = getWebView(m_webFrame.get());
401 [[webView _frameLoadDelegateForwarder] webView:webView willCloseFrame:m_webFrame.get()];
404 void WebFrameLoaderClient::dispatchDidReceiveIcon()
406 WebView *webView = getWebView(m_webFrame.get());
407 ASSERT([m_webFrame.get() _isMainFrame]);
408 // FIXME: This willChangeValueForKey call is too late, because the icon has already changed by now.
409 [webView _willChangeValueForKey:_WebMainFrameIconKey];
410 id delegate = [webView frameLoadDelegate];
411 if ([delegate respondsToSelector:@selector(webView:didReceiveIcon:forFrame:)]) {
412 Image* image = IconDatabase::sharedIconDatabase()->
413 iconForPageURL(core(m_webFrame.get())->loader()->url().url(), IntSize(16, 16));
414 NSImage *icon = webGetNSImage(image, NSMakeSize(16, 16));
416 [delegate webView:webView didReceiveIcon:icon forFrame:m_webFrame.get()];
418 [webView _didChangeValueForKey:_WebMainFrameIconKey];
421 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
423 WebView *webView = getWebView(m_webFrame.get());
424 [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
425 [[webView _frameLoadDelegateForwarder] webView:webView didStartProvisionalLoadForFrame:m_webFrame.get()];
428 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
430 WebView *webView = getWebView(m_webFrame.get());
431 [[webView _frameLoadDelegateForwarder] webView:webView didReceiveTitle:title forFrame:m_webFrame.get()];
434 void WebFrameLoaderClient::dispatchDidCommitLoad()
436 // Tell the client we've committed this URL.
437 ASSERT([m_webFrame->_private->webFrameView documentView] != nil);
439 WebView *webView = getWebView(m_webFrame.get());
440 [webView _didCommitLoadForFrame:m_webFrame.get()];
441 [[webView _frameLoadDelegateForwarder] webView:webView didCommitLoadForFrame:m_webFrame.get()];
444 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
446 WebView *webView = getWebView(m_webFrame.get());
447 [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
448 [[webView _frameLoadDelegateForwarder] webView:webView didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
449 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
452 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
454 WebView *webView = getWebView(m_webFrame.get());
455 [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
456 [[webView _frameLoadDelegateForwarder] webView:webView didFailLoadWithError:error forFrame:m_webFrame.get()];
457 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
460 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
462 WebView *webView = getWebView(m_webFrame.get());
463 id delegate = [webView frameLoadDelegate];
464 if ([delegate respondsToSelector:@selector(webView:didFinishDocumentLoadForFrame:)])
465 [delegate webView:webView didFinishDocumentLoadForFrame:m_webFrame.get()];
468 void WebFrameLoaderClient::dispatchDidFinishLoad()
470 WebView *webView = getWebView(m_webFrame.get());
471 [webView _didFinishLoadForFrame:m_webFrame.get()];
472 [[webView _frameLoadDelegateForwarder] webView:webView didFinishLoadForFrame:m_webFrame.get()];
473 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
476 void WebFrameLoaderClient::dispatchDidFirstLayout()
478 WebView *webView = getWebView(m_webFrame.get());
479 [[webView _frameLoadDelegateForwarder] webView:webView didFirstLayoutInFrame:m_webFrame.get()];
482 Frame* WebFrameLoaderClient::dispatchCreatePage()
484 WebView *currentWebView = getWebView(m_webFrame.get());
485 id wd = [currentWebView UIDelegate];
486 if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
487 return core([[wd webView:currentWebView createWebViewWithRequest:nil] mainFrame]);
491 void WebFrameLoaderClient::dispatchShow()
493 WebView *webView = getWebView(m_webFrame.get());
494 [[webView _UIDelegateForwarder] webViewShow:webView];
497 void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction function,
498 const String& MIMEType, const ResourceRequest& request)
500 WebView *webView = getWebView(m_webFrame.get());
502 [[webView _policyDelegateForwarder] webView:webView
503 decidePolicyForMIMEType:MIMEType
504 request:request.nsURLRequest()
505 frame:m_webFrame.get()
506 decisionListener:setUpPolicyListener(function).get()];
509 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
510 const NavigationAction& action, const ResourceRequest& request, const String& frameName)
512 WebView *webView = getWebView(m_webFrame.get());
513 [[webView _policyDelegateForwarder] webView:webView
514 decidePolicyForNewWindowAction:actionDictionary(action)
515 request:request.nsURLRequest()
516 newFrameName:frameName
517 decisionListener:setUpPolicyListener(function).get()];
520 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
521 const NavigationAction& action, const ResourceRequest& request)
523 WebView *webView = getWebView(m_webFrame.get());
524 [[webView _policyDelegateForwarder] webView:webView
525 decidePolicyForNavigationAction:actionDictionary(action)
526 request:request.nsURLRequest()
527 frame:m_webFrame.get()
528 decisionListener:setUpPolicyListener(function).get()];
531 void WebFrameLoaderClient::cancelPolicyCheck()
533 [m_policyListener.get() invalidate];
534 m_policyListener = nil;
535 m_policyFunction = 0;
538 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
540 WebView *webView = getWebView(m_webFrame.get());
541 [[webView _policyDelegateForwarder] webView:webView
542 unableToImplementPolicyWithError:error frame:m_webFrame.get()];
545 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
547 id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
549 (core(m_webFrame.get())->loader()->*function)(PolicyUse);
553 NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:formState->values().size()];
554 HashMap<String, String>::const_iterator end = formState->values().end();
555 for (HashMap<String, String>::const_iterator it = formState->values().begin(); it != end; ++it)
556 if (!it->first.isNull() && !it->second.isNull())
557 [dictionary setObject:it->second forKey:it->first];
559 [formDelegate frame:m_webFrame.get()
560 sourceFrame:kit(formState->sourceFrame())
561 willSubmitForm:kit(formState->form())
562 withValues:dictionary
563 submissionListener:setUpPolicyListener(function).get()];
565 [dictionary release];
568 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
570 if ([WebScriptDebugServer listenerCount])
571 [[WebScriptDebugServer sharedScriptDebugServer] webView:getWebView(m_webFrame.get())
572 didLoadMainResourceForDataSource:dataSource(loader)];
575 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
577 [dataSource(loader) _revertToProvisionalState];
580 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
582 [dataSource(loader) _setMainDocumentError:error];
585 void WebFrameLoaderClient::clearUnarchivingState(DocumentLoader* loader)
587 [dataSource(loader) _clearUnarchivingState];
590 void WebFrameLoaderClient::willChangeEstimatedProgress()
592 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
595 void WebFrameLoaderClient::didChangeEstimatedProgress()
597 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
600 void WebFrameLoaderClient::postProgressStartedNotification()
602 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
605 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
607 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
610 void WebFrameLoaderClient::postProgressFinishedNotification()
612 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
615 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
617 [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
620 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
622 // FIXME: Should download full request.
623 [getWebView(m_webFrame.get()) _downloadURL:request.url().getNSURL()];
626 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
628 // FIXME: Should do this only in main frame case, right?
629 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
632 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
634 // FIXME: Should do this only in main frame case, right?
635 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
638 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
640 NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
641 [dataSource(loader) _receivedData:nsData];
645 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
647 [dataSource(loader) _finishedLoading];
650 void WebFrameLoaderClient::finalSetupForReplace(DocumentLoader* loader)
652 [dataSource(loader) _clearUnarchivingState];
655 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
656 // Once that task is complete, this will go away
657 void WebFrameLoaderClient::updateGlobalHistoryForStandardLoad(const KURL& url)
659 NSURL *nsurl = url.getNSURL();
660 WebHistoryItem *entry = [[WebHistory optionalSharedHistory] addItemForURL:nsurl];
661 String pageTitle = core(m_webFrame.get())->loader()->documentLoader()->title();
662 if (pageTitle.length())
663 [entry setTitle:pageTitle];
666 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
667 // Once that task is complete, this will go away
668 void WebFrameLoaderClient::updateGlobalHistoryForReload(const KURL& url)
670 WebHistory *sharedHistory = [WebHistory optionalSharedHistory];
671 WebHistoryItem *item = [sharedHistory itemForURL:url.getNSURL()];
673 [sharedHistory setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate] forItem:item];
676 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
678 WebView* view = getWebView(m_webFrame.get());
679 WebHistoryItem *webItem = kit(item);
681 return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
684 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest &request)
686 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url().getNSURL()];
689 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
691 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url().getNSURL()];
694 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
696 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url().getNSURL()];
699 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
701 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url().getNSURL()];
704 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
706 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url().getNSURL()];
709 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
711 // FIXME: Needs to check domain.
712 // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
713 // loading plugin content twice. See <rdar://problem/4258008>
714 return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
717 void WebFrameLoaderClient::setDefersLoading(bool defers)
720 deliverArchivedResourcesAfterDelay();
723 bool WebFrameLoaderClient::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const
725 if (request.url() != originalURL)
727 if (!canUseArchivedResource(request.nsURLRequest()))
729 WebResource *resource = [dataSource(core(m_webFrame.get())->loader()->activeDocumentLoader()) _archivedSubresourceForURL:originalURL.getNSURL()];
732 if (!canUseArchivedResource([resource _response]))
734 m_pendingArchivedResources.set(loader, resource);
735 // Deliver the resource after a delay because callers don't expect to receive callbacks while calling this method.
736 deliverArchivedResourcesAfterDelay();
740 bool WebFrameLoaderClient::isArchiveLoadPending(ResourceLoader* loader) const
742 return m_pendingArchivedResources.contains(loader);
745 void WebFrameLoaderClient::cancelPendingArchiveLoad(ResourceLoader* loader)
747 if (m_pendingArchivedResources.isEmpty())
749 m_pendingArchivedResources.remove(loader);
750 if (m_pendingArchivedResources.isEmpty())
751 m_archivedResourcesDeliveryTimer.stop();
754 void WebFrameLoaderClient::clearArchivedResources()
756 m_pendingArchivedResources.clear();
757 m_archivedResourcesDeliveryTimer.stop();
760 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
762 return [WebView _canHandleRequest:request.nsURLRequest()];
765 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
767 return [WebView canShowMIMEType:MIMEType];
770 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
772 return [WebView _representationExistsForURLScheme:URLScheme];
775 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
777 return [WebView _generatedMIMETypeForURLScheme:URLScheme];
780 void WebFrameLoaderClient::frameLoadCompleted()
782 // Note: Can be called multiple times.
783 // Even if already complete, we might have set a previous item on a frame that
784 // didn't do any data loading on the past transaction. Make sure to clear these out.
785 NSScrollView *sv = [m_webFrame->_private->webFrameView _scrollView];
786 if ([getWebView(m_webFrame.get()) drawsBackground])
787 [sv setDrawsBackground:YES];
788 core(m_webFrame.get())->loader()->setPreviousHistoryItem(0);
792 void WebFrameLoaderClient::saveScrollPositionAndViewStateToItem(HistoryItem* item)
797 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
798 NSView *parent = [docView superview];
800 // we might already be detached when this is called from detachFromParent, in which
801 // case we don't want to override real data earlier gathered with (0,0)
804 if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
805 // The view has it's own idea of where it is scrolled to, perhaps because it contains its own
806 // ScrollView instead of using the one provided by the WebFrame
807 point = [(id <_WebDocumentViewState>)docView scrollPoint];
808 item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
810 // Parent is the clipview of the DynamicScrollView the WebFrame installs
811 ASSERT([parent isKindOfClass:[NSClipView class]]);
812 point = [parent bounds].origin;
814 item->setScrollPoint(IntPoint(point));
819 There is a race condition between the layout and load completion that affects restoring the scroll position.
820 We try to restore the scroll position at both the first layout and upon load completion.
822 1) If first layout happens before the load completes, we want to restore the scroll position then so that the
823 first time we draw the page is already scrolled to the right place, instead of starting at the top and later
824 jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in
825 which case the restore silent fails and we will fix it in when we try to restore on doc completion.
826 2) If the layout happens after the load completes, the attempt to restore at load completion time silently
827 fails. We then successfully restore it when the layout happens.
829 void WebFrameLoaderClient::restoreScrollPositionAndViewState()
831 HistoryItem* currentItem = core(m_webFrame.get())->loader()->currentHistoryItem();
834 // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
835 // One counterexample is <rdar://problem/4917290>
836 // For now, to cover this issue in release builds, there is no technical harm to returning
837 // early and from a user standpoint - as in the above radar - the previous page load failed
838 // so there *is* no scroll state to restore!
842 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
843 NSPoint point = currentItem->scrollPoint();
844 if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
845 id state = currentItem->viewState();
847 [(id <_WebDocumentViewState>)docView setViewState:state];
850 [(id <_WebDocumentViewState>)docView setScrollPoint:point];
852 [docView scrollPoint:point];
856 void WebFrameLoaderClient::provisionalLoadStarted()
858 // FIXME: This is OK as long as no one resizes the window,
859 // but in the case where someone does, it means garbage outside
860 // the occupied part of the scroll view.
861 [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:NO];
864 void WebFrameLoaderClient::didFinishLoad()
866 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
869 void WebFrameLoaderClient::prepareForDataSourceReplacement()
871 if (![m_webFrame.get() dataSource]) {
872 ASSERT(!core(m_webFrame.get())->tree()->childCount());
876 // Make sure that any work that is triggered by resigning first reponder can get done.
877 // The main example where this came up is the textDidEndEditing that is sent to the
878 // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
879 // remove the views as a side-effect of freeing the bridge, at which point we can't
880 // post the FormDelegate messages.
882 // Note that this can also take FirstResponder away from a child of our frameView that
883 // is not in a child frame's view. This is OK because we are in the process
884 // of loading new content, which will blow away all editors in this top frame, and if
885 // a non-editor is firstReponder it will not be affected by endEditingFor:.
886 // Potentially one day someone could write a DocView whose editors were not all
887 // replaced by loading new content, but that does not apply currently.
888 NSView *frameView = m_webFrame->_private->webFrameView;
889 NSWindow *window = [frameView window];
890 NSResponder *firstResp = [window firstResponder];
891 if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
892 [window endEditingFor:firstResp];
894 core(m_webFrame.get())->loader()->detachChildren();
897 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request)
899 RefPtr<WebDocumentLoaderMac> loader = new WebDocumentLoaderMac(request);
901 WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
902 loader->setDataSource(dataSource);
903 [dataSource release];
905 return loader.release();
908 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
909 // Once that task is complete, this will go away
910 void WebFrameLoaderClient::setTitle(const String& title, const KURL& URL)
912 NSURL* nsURL = canonicalURL(URL.getNSURL());
915 NSString *titleNSString = title;
916 [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
917 if (HistoryItem* item = core(m_webFrame.get())->loader()->currentHistoryItem())
918 item->setTitle(title);
921 // The following 2 functions are copied from [NSHTTPURLProtocol _cachedResponsePassesValidityChecks] and modified for our needs.
922 // FIXME: It would be nice to eventually to share this logic somehow.
923 bool WebFrameLoaderClient::canUseArchivedResource(NSURLRequest *request) const
925 NSURLRequestCachePolicy policy = [request cachePolicy];
926 if (policy == NSURLRequestReturnCacheDataElseLoad)
928 if (policy == NSURLRequestReturnCacheDataDontLoad)
930 if (policy == NSURLRequestReloadIgnoringCacheData)
932 if ([request valueForHTTPHeaderField:@"must-revalidate"] != nil)
934 if ([request valueForHTTPHeaderField:@"proxy-revalidate"] != nil)
936 if ([request valueForHTTPHeaderField:@"If-Modified-Since"] != nil)
938 if ([request valueForHTTPHeaderField:@"Cache-Control"] != nil)
940 if ([@"POST" _webkit_isCaseInsensitiveEqualToString:[request HTTPMethod]])
945 bool WebFrameLoaderClient::canUseArchivedResource(NSURLResponse *response) const
947 if (WKGetNSURLResponseMustRevalidate(response))
949 if (WKGetNSURLResponseCalculatedExpiration(response) - CFAbsoluteTimeGetCurrent() < 1)
954 void WebFrameLoaderClient::deliverArchivedResourcesAfterDelay() const
956 if (m_pendingArchivedResources.isEmpty())
958 if (core(m_webFrame.get())->page()->defersLoading())
960 if (!m_archivedResourcesDeliveryTimer.isActive())
961 m_archivedResourcesDeliveryTimer.startOneShot(0);
964 void WebFrameLoaderClient::deliverArchivedResources(Timer<WebFrameLoaderClient>*)
966 if (m_pendingArchivedResources.isEmpty())
968 if (core(m_webFrame.get())->page()->defersLoading())
971 const ResourceMap copy = m_pendingArchivedResources;
972 m_pendingArchivedResources.clear();
974 ResourceMap::const_iterator end = copy.end();
975 for (ResourceMap::const_iterator it = copy.begin(); it != end; ++it) {
976 RefPtr<ResourceLoader> loader = it->first;
977 WebResource *resource = it->second.get();
978 NSData *data = [[resource data] retain];
979 loader->didReceiveResponse([resource _response]);
980 loader->didReceiveData((const char*)[data bytes], [data length], [data length], true);
982 loader->didFinishLoading();
986 void WebFrameLoaderClient::saveDocumentViewToPageCache(PageCache* pageCache)
988 pageCache->setDocumentView([m_webFrame->_private->webFrameView documentView]);
991 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
993 ASSERT(!m_policyListener);
994 ASSERT(!m_policyFunction);
996 [m_policyListener.get() invalidate];
998 WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
999 m_policyListener = listener;
1001 m_policyFunction = function;
1006 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1008 ASSERT(m_policyListener);
1009 ASSERT(m_policyFunction);
1011 FramePolicyFunction function = m_policyFunction;
1013 m_policyListener = nil;
1014 m_policyFunction = 0;
1016 (core(m_webFrame.get())->loader()->*function)(action);
1019 String WebFrameLoaderClient::userAgent()
1021 return [getWebView(m_webFrame.get()) _userAgent];
1024 static const MouseEvent* findMouseEvent(const Event* event)
1026 for (const Event* e = event; e; e = e->underlyingEvent())
1027 if (e->isMouseEvent())
1028 return static_cast<const MouseEvent*>(e);
1032 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action) const
1034 unsigned modifierFlags = 0;
1035 const Event* event = action.event();
1036 if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1037 if (keyStateEvent->ctrlKey())
1038 modifierFlags |= NSControlKeyMask;
1039 if (keyStateEvent->altKey())
1040 modifierFlags |= NSAlternateKeyMask;
1041 if (keyStateEvent->shiftKey())
1042 modifierFlags |= NSShiftKeyMask;
1043 if (keyStateEvent->metaKey())
1044 modifierFlags |= NSCommandKeyMask;
1046 if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1047 IntPoint point(mouseEvent->clientX(), mouseEvent->clientY());
1048 WebElementDictionary *element = [[WebElementDictionary alloc]
1049 initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(point, false)];
1050 NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:
1051 [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1052 element, WebActionElementKey,
1053 [NSNumber numberWithInt:mouseEvent->button()], WebActionButtonKey,
1054 [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1055 action.URL().getNSURL(), WebActionOriginalURLKey,
1060 return [NSDictionary dictionaryWithObjectsAndKeys:
1061 [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1062 [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1063 action.URL().getNSURL(), WebActionOriginalURLKey,
1067 bool WebFrameLoaderClient::canCachePage() const
1069 // We can only cache HTML pages right now
1070 return [[[m_webFrame.get() dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1073 Frame* WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1074 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1076 WebFrameBridge* bridge = m_webFrame->_private->bridge;
1077 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1079 return [bridge createChildFrameNamed:name
1080 withURL:url.getNSURL()
1082 ownerElement:ownerElement
1083 allowsScrolling:allowsScrolling
1084 marginWidth:marginWidth
1085 marginHeight:marginHeight];
1087 END_BLOCK_OBJC_EXCEPTIONS;
1091 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType)
1093 WebFrameBridge* bridge = m_webFrame->_private->bridge;
1094 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1095 return (ObjectContentType)[bridge determineObjectFromMIMEType:mimeType URL:url.getNSURL()];
1096 END_BLOCK_OBJC_EXCEPTIONS;
1097 return ObjectContentNone;
1100 static NSArray* nsArray(const Vector<String>& vector)
1102 unsigned len = vector.size();
1103 NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1104 for (unsigned x = 0; x < len; x++)
1105 [array addObject:vector[x]];
1109 Widget* WebFrameLoaderClient::createPlugin(Element* element, const KURL& url, const Vector<String>& paramNames,
1110 const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1112 WebFrameBridge* bridge = m_webFrame->_private->bridge;
1114 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1115 return new Widget([bridge viewForPluginWithURL:url.getNSURL()
1116 attributeNames:nsArray(paramNames)
1117 attributeValues:nsArray(paramValues)
1119 DOMElement:[DOMElement _elementWith:element]
1120 loadManually:loadManually]);
1121 END_BLOCK_OBJC_EXCEPTIONS;
1126 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1128 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1129 [m_webFrame->_private->bridge redirectDataToPlugin:pluginWidget->getView()];
1130 END_BLOCK_OBJC_EXCEPTIONS;
1133 WebCore::Widget* WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, Element* element, const KURL& baseURL,
1134 const Vector<String>& paramNames, const Vector<String>& paramValues)
1136 Widget* result = new Widget;
1138 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1139 WebFrameBridge* bridge = m_webFrame->_private->bridge;
1140 result->setView([bridge viewForJavaAppletWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1141 attributeNames:nsArray(paramNames)
1142 attributeValues:nsArray(paramValues)
1143 baseURL:baseURL.getNSURL()
1144 DOMElement:[DOMElement _elementWith:element]]);
1145 END_BLOCK_OBJC_EXCEPTIONS;
1150 String WebFrameLoaderClient::overrideMediaType() const
1152 NSString* overrideType = [m_webFrame->_private->bridge overrideMediaType];
1154 return overrideType;
1158 void WebFrameLoaderClient::windowObjectCleared() const
1160 [m_webFrame->_private->bridge windowObjectCleared];
1163 @implementation WebFramePolicyListener
1165 - (id)initWithWebCoreFrame:(Frame*)frame
1197 - (void)receivedPolicyDecision:(PolicyAction)action
1199 RefPtr<Frame> frame = adoptRef(m_frame);
1202 static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
1207 [self receivedPolicyDecision:PolicyIgnore];
1212 [self receivedPolicyDecision:PolicyDownload];
1217 [self receivedPolicyDecision:PolicyUse];
1222 [self receivedPolicyDecision:PolicyUse];