57c5a68a59e8abaa0bfb7c680a3d8d84ae9a2c48
[WebKit-https.git] / Source / WebKit / mac / WebCoreSupport / WebFrameLoaderClient.mm
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 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  *
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. 
16  *
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.
27  */
28
29 #import "WebFrameLoaderClient.h"
30
31 // Terrible hack; lets us get at the WebFrame private structure.
32 #define private public
33 #import "WebFrame.h"
34 #undef private
35
36 #import "DOMElementInternal.h"
37 #import "WebBackForwardList.h"
38 #import "WebCachedFramePlatformData.h"
39 #import "WebChromeClient.h"
40 #import "WebDataSourceInternal.h"
41 #import "WebDelegateImplementationCaching.h"
42 #import "WebDocumentInternal.h"
43 #import "WebDocumentLoaderMac.h"
44 #import "WebDownloadInternal.h"
45 #import "WebDynamicScrollBarsViewInternal.h"
46 #import "WebElementDictionary.h"
47 #import "WebFormDelegate.h"
48 #import "WebFrameInternal.h"
49 #import "WebFrameLoadDelegate.h"
50 #import "WebFrameNetworkingContext.h"
51 #import "WebFrameViewInternal.h"
52 #import "WebHTMLRepresentationPrivate.h"
53 #import "WebHTMLViewInternal.h"
54 #import "WebHistoryInternal.h"
55 #import "WebHistoryItemInternal.h"
56 #import "WebIconDatabaseInternal.h"
57 #import "WebKitErrorsPrivate.h"
58 #import "WebKitLogging.h"
59 #import "WebKitNSStringExtras.h"
60 #import "WebNSURLExtras.h"
61 #import "WebNavigationData.h"
62 #import "WebNetscapePluginPackage.h"
63 #import "WebNetscapePluginView.h"
64 #import "WebPanelAuthenticationHandler.h"
65 #import "WebPluginController.h"
66 #import "WebPluginPackage.h"
67 #import "WebPluginViewFactoryPrivate.h"
68 #import "WebPolicyDelegate.h"
69 #import "WebPolicyDelegatePrivate.h"
70 #import "WebPreferences.h"
71 #import "WebResourceLoadDelegate.h"
72 #import "WebScriptWorldInternal.h"
73 #import "WebSecurityOriginInternal.h"
74 #import "WebUIDelegate.h"
75 #import "WebUIDelegatePrivate.h"
76 #import "WebViewInternal.h"
77 #import <WebCore/AuthenticationCF.h>
78 #import <WebCore/AuthenticationMac.h>
79 #import <WebCore/BackForwardController.h>
80 #import <WebCore/BlockExceptions.h>
81 #import <WebCore/CachedFrame.h>
82 #import <WebCore/Chrome.h>
83 #import <WebCore/Document.h>
84 #import <WebCore/DocumentLoader.h>
85 #import <WebCore/EventHandler.h>
86 #import <WebCore/FocusController.h>
87 #import <WebCore/FormState.h>
88 #import <WebCore/Frame.h>
89 #import <WebCore/FrameLoader.h>
90 #import <WebCore/FrameLoaderStateMachine.h>
91 #import <WebCore/FrameLoaderTypes.h>
92 #import <WebCore/FrameTree.h>
93 #import <WebCore/FrameView.h>
94 #import <WebCore/HTMLAppletElement.h>
95 #import <WebCore/HTMLFormElement.h>
96 #import <WebCore/HTMLFrameElement.h>
97 #import <WebCore/HTMLFrameOwnerElement.h>
98 #import <WebCore/HTMLHeadElement.h>
99 #import <WebCore/HTMLNames.h>
100 #import <WebCore/HTMLParserIdioms.h>
101 #import <WebCore/HTMLPlugInElement.h>
102 #import <WebCore/HistoryItem.h>
103 #import <WebCore/HitTestResult.h>
104 #import <WebCore/IconDatabase.h>
105 #import <WebCore/LoaderNSURLExtras.h>
106 #import <WebCore/MIMETypeRegistry.h>
107 #import <WebCore/MainResourceLoader.h>
108 #import <WebCore/MouseEvent.h>
109 #import <WebCore/Page.h>
110 #import <WebCore/PluginViewBase.h>
111 #import <WebCore/ProtectionSpace.h>
112 #import <WebCore/ResourceError.h>
113 #import <WebCore/ResourceHandle.h>
114 #import <WebCore/ResourceLoader.h>
115 #import <WebCore/ResourceRequest.h>
116 #import <WebCore/RunLoop.h>
117 #import <WebCore/ScriptController.h>
118 #import <WebCore/SharedBuffer.h>
119 #import <WebCore/WebCoreObjCExtras.h>
120 #import <WebCore/Widget.h>
121 #import <WebKit/DOMElement.h>
122 #import <WebKit/DOMHTMLFormElement.h>
123 #import <WebKitSystemInterface.h>
124 #import <runtime/InitializeThreading.h>
125 #import <wtf/MainThread.h>
126 #import <wtf/PassRefPtr.h>
127 #import <wtf/text/WTFString.h>
128
129 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
130 #import <WebCore/HTMLMediaElement.h>
131 #endif
132
133 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
134 #import "NetscapePluginHostManager.h"
135 #import "WebHostedNetscapePluginView.h"
136 #endif
137
138 using namespace WebCore;
139 using namespace HTMLNames;
140 using namespace std;
141
142 // For backwards compatibility with older WebKit plug-ins.
143 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
144 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
145 NSString *WebPluginContainerKey = @"WebPluginContainer";
146
147 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> {
148     Frame* m_frame;
149 }
150 - (id)initWithWebCoreFrame:(Frame*)frame;
151 - (void)invalidate;
152 @end
153
154 static inline WebDataSource *dataSource(DocumentLoader* loader)
155 {
156     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
157 }
158
159 // Quirk for the Apple Dictionary application.
160 //
161 // If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,
162 // then for that frame's document, ignore changes to the scrolling attribute of frames. That script
163 // has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling
164 // attribute needs to be ignored to avoid showing extra scroll bars in the window.
165 // This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).
166
167 static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request)
168 {
169     if (!request.url().isLocalFile())
170         return;
171     if (!request.url().string().endsWith("MainPageJavaScript.js"))
172         return;
173     Frame* frame = core(client->webFrame());
174     if (!frame)
175         return;
176     if (frame->tree()->parent())
177         return;
178     Document* document = frame->document();
179     if (!document)
180         return;
181     HTMLHeadElement* head = document->head();
182     if (!head)
183         return;
184     for (Node* c = head->firstChild(); c; c = c->nextSibling()) {
185         if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") {
186             document->setFrameElementsShouldIgnoreScrolling(true);
187             return;
188         }
189     }
190 }
191
192 static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request)
193 {
194     // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in
195     // all applications other than Apple Dictionary.
196     static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"];
197     if (isAppleDictionary)
198         applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);
199 }
200
201 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
202     : m_webFrame(webFrame)
203     , m_policyFunction(0)
204 {
205 }
206
207 void WebFrameLoaderClient::frameLoaderDestroyed()
208 {
209     [m_webFrame.get() _clearCoreFrame];
210     delete this;
211 }
212
213 bool WebFrameLoaderClient::hasWebView() const
214 {
215     return [m_webFrame.get() webView] != nil;
216 }
217
218 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
219 {
220     [dataSource(loader) _makeRepresentation];
221 }
222
223 bool WebFrameLoaderClient::hasHTMLView() const
224 {
225     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
226     return [view isKindOfClass:[WebHTMLView class]];
227 }
228
229 void WebFrameLoaderClient::forceLayout()
230 {
231     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
232     [view setNeedsLayout:YES];
233     [view layout];
234 }
235
236 void WebFrameLoaderClient::forceLayoutForNonHTML()
237 {
238     WebFrameView *thisView = m_webFrame->_private->webFrameView;
239     NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
240     ASSERT(thisDocumentView != nil);
241     
242     // Tell the just loaded document to layout.  This may be necessary
243     // for non-html content that needs a layout message.
244     if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) {
245         [thisDocumentView setNeedsLayout:YES];
246         [thisDocumentView layout];
247         [thisDocumentView setNeedsDisplay:YES];
248     }
249 }
250
251 void WebFrameLoaderClient::setCopiesOnScroll()
252 {
253     [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
254 }
255
256 void WebFrameLoaderClient::detachedFromParent2()
257 {
258     //remove any NetScape plugins that are children of this frame because they are about to be detached
259     WebView *webView = getWebView(m_webFrame.get());
260     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
261     [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
262 }
263
264 void WebFrameLoaderClient::detachedFromParent3()
265 {
266     [m_webFrame->_private->webFrameView release];
267     m_webFrame->_private->webFrameView = nil;
268 }
269
270 void WebFrameLoaderClient::convertMainResourceLoadToDownload(MainResourceLoader* mainResourceLoader, const ResourceRequest& request, const ResourceResponse& response)
271 {
272     ResourceHandle* handle = mainResourceLoader->loader()->handle();
273
274 #if USE(CFNETWORK)
275     ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
276     WebView *webView = getWebView(m_webFrame.get());
277     CFURLConnectionRef connection = handle->connection();
278     [WebDownload _downloadWithLoadingCFURLConnection:connection
279                                                                      request:request.cfURLRequest()
280                                                                     response:response.cfURLResponse()
281                                                                     delegate:[webView downloadDelegate]
282                                                                        proxy:nil];
283
284     // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
285     handle->releaseConnectionForDownload();
286     CFRelease(connection);
287 #else
288     id proxy = handle->releaseProxy();
289     ASSERT(proxy);
290     
291     WebView *webView = getWebView(m_webFrame.get());
292     [WebDownload _downloadWithLoadingConnection:handle->connection()
293                                                                 request:request.nsURLRequest()
294                                                                response:response.nsURLResponse()
295                                                                delegate:[webView downloadDelegate]
296                                                                   proxy:proxy];
297 #endif
298 }
299
300 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
301 {
302     applyAppleDictionaryApplicationQuirk(this, request);
303
304     WebView *webView = getWebView(m_webFrame.get());
305     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
306     if (!implementations->didLoadResourceFromMemoryCacheFunc)
307         return false;
308
309     CallResourceLoadDelegate(implementations->didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
310     return true;
311 }
312
313 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
314 {
315     WebView *webView = getWebView(m_webFrame.get());
316     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
317
318     id object = nil;
319     BOOL shouldRelease = NO;
320     if (implementations->identifierForRequestFunc)
321         object = CallResourceLoadDelegate(implementations->identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
322     else {
323         object = [[NSObject alloc] init];
324         shouldRelease = YES;
325     }
326
327     [webView _addObject:object forIdentifier:identifier];
328
329     if (shouldRelease)
330         [object release];
331 }
332
333 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
334 {
335     applyAppleDictionaryApplicationQuirk(this, request);
336
337     WebView *webView = getWebView(m_webFrame.get());
338     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
339
340     if (redirectResponse.isNull())
341         static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
342
343     NSURLRequest *currentURLRequest = request.nsURLRequest();
344     NSURLRequest *newURLRequest = currentURLRequest;
345     if (implementations->willSendRequestFunc)
346         newURLRequest = (NSURLRequest *)CallResourceLoadDelegate(implementations->willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], currentURLRequest, redirectResponse.nsURLResponse(), dataSource(loader));
347
348     if (newURLRequest != currentURLRequest)
349         request = newURLRequest;
350 }
351
352 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
353 {
354     WebView *webView = getWebView(m_webFrame.get());
355     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
356
357     if (implementations->shouldUseCredentialStorageFunc) {
358         if (id resource = [webView _objectForIdentifier:identifier])
359             return CallResourceLoadDelegateReturningBoolean(NO, implementations->shouldUseCredentialStorageFunc, webView, @selector(webView:resource:shouldUseCredentialStorageForDataSource:), resource, dataSource(loader));
360     }
361
362     return true;
363 }
364
365 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
366 {
367     WebView *webView = getWebView(m_webFrame.get());
368     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
369
370     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
371
372     if (implementations->didReceiveAuthenticationChallengeFunc) {
373         if (id resource = [webView _objectForIdentifier:identifier]) {
374             CallResourceLoadDelegate(implementations->didReceiveAuthenticationChallengeFunc, webView, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
375             return;
376         }
377     }
378
379     NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
380     [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
381 }
382
383 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
384 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader* loader, unsigned long identifier, const ProtectionSpace& protectionSpace)
385 {
386     WebView *webView = getWebView(m_webFrame.get());
387     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
388     
389     NSURLProtectionSpace *webProtectionSpace = mac(protectionSpace);
390     
391     if (implementations->canAuthenticateAgainstProtectionSpaceFunc) {
392         if (id resource = [webView _objectForIdentifier:identifier]) {
393             return CallResourceLoadDelegateReturningBoolean(NO, implementations->canAuthenticateAgainstProtectionSpaceFunc, webView, @selector(webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:), resource, webProtectionSpace, dataSource(loader));
394         }
395     }
396
397     // If our resource load delegate doesn't handle the question, then only send authentication
398     // challenges for pre-10.6 protection spaces.  This is the same as the default implementation
399     // in CFNetwork.
400     return (protectionSpace.authenticationScheme() < ProtectionSpaceAuthenticationSchemeClientCertificateRequested);
401 }
402 #endif
403
404 bool WebFrameLoaderClient::shouldPaintBrokenImage(const KURL& imageURL) const
405 {
406     WebView *webView = getWebView(m_webFrame.get());
407     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
408
409     if (implementations->shouldPaintBrokenImageForURLFunc) {
410         NSURL* url = imageURL;
411         return CallResourceLoadDelegateReturningBoolean(YES, implementations->shouldPaintBrokenImageForURLFunc, webView, @selector(webView:shouldPaintBrokenImageForURL:), url);
412     }
413     return true;
414 }
415
416 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
417 {
418     WebView *webView = getWebView(m_webFrame.get());
419     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
420     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
421
422     if (implementations->didCancelAuthenticationChallengeFunc) {
423         if (id resource = [webView _objectForIdentifier:identifier]) {
424             CallResourceLoadDelegate(implementations->didCancelAuthenticationChallengeFunc, webView, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
425             return;
426         }
427     }
428
429     [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
430 }
431
432 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
433 {
434     WebView *webView = getWebView(m_webFrame.get());
435     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
436     if (implementations->didReceiveResponseFunc) {
437         if (id resource = [webView _objectForIdentifier:identifier])
438             CallResourceLoadDelegate(implementations->didReceiveResponseFunc, webView, @selector(webView:resource:didReceiveResponse:fromDataSource:), resource, response.nsURLResponse(), dataSource(loader));
439     }
440 }
441
442 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loader, unsigned long identifier, NSCachedURLResponse* response) const
443 {
444     WebView *webView = getWebView(m_webFrame.get());
445     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
446
447     if (implementations->willCacheResponseFunc) {
448         if (id resource = [webView _objectForIdentifier:identifier])
449             return CallResourceLoadDelegate(implementations->willCacheResponseFunc, webView, @selector(webView:resource:willCacheResponse:fromDataSource:), resource, response, dataSource(loader));
450     }
451
452     return response;
453 }
454
455 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int dataLength)
456 {
457     WebView *webView = getWebView(m_webFrame.get());
458     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
459     if (implementations->didReceiveContentLengthFunc) {
460         if (id resource = [webView _objectForIdentifier:identifier])
461             CallResourceLoadDelegate(implementations->didReceiveContentLengthFunc, webView, @selector(webView:resource:didReceiveContentLength:fromDataSource:), resource, (NSInteger)dataLength, dataSource(loader));
462     }
463 }
464
465 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
466 {
467     WebView *webView = getWebView(m_webFrame.get());
468     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
469
470     if (implementations->didFinishLoadingFromDataSourceFunc) {
471         if (id resource = [webView _objectForIdentifier:identifier])
472             CallResourceLoadDelegate(implementations->didFinishLoadingFromDataSourceFunc, webView, @selector(webView:resource:didFinishLoadingFromDataSource:), resource, dataSource(loader));
473     }
474
475     [webView _removeObjectForIdentifier:identifier];
476
477     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
478 }
479
480 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
481 {
482     WebView *webView = getWebView(m_webFrame.get());
483     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
484
485     if (implementations->didFailLoadingWithErrorFromDataSourceFunc) {
486         if (id resource = [webView _objectForIdentifier:identifier])
487             CallResourceLoadDelegate(implementations->didFailLoadingWithErrorFromDataSourceFunc, webView, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), resource, (NSError *)error, dataSource(loader));
488     }
489
490     [webView _removeObjectForIdentifier:identifier];
491
492     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
493 }
494
495 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
496 {
497     WebView *webView = getWebView(m_webFrame.get());
498     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
499     if (implementations->didHandleOnloadEventsForFrameFunc)
500         CallFrameLoadDelegate(implementations->didHandleOnloadEventsForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
501 }
502
503 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
504 {
505     WebView *webView = getWebView(m_webFrame.get());
506     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
507     if (implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc)
508         CallFrameLoadDelegate(implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc, webView, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:), m_webFrame.get());
509 }
510
511 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
512 {
513     WebView *webView = getWebView(m_webFrame.get());
514     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
515     if (implementations->didCancelClientRedirectForFrameFunc)
516         CallFrameLoadDelegate(implementations->didCancelClientRedirectForFrameFunc, webView, @selector(webView:didCancelClientRedirectForFrame:), m_webFrame.get());
517 }
518
519 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
520 {
521     WebView *webView = getWebView(m_webFrame.get());
522     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
523     if (implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc) {
524         NSURL *cocoaURL = url;
525         CallFrameLoadDelegate(implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc, webView, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), cocoaURL, delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
526     }
527 }
528
529 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
530 {
531     WebView *webView = getWebView(m_webFrame.get());
532     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
533     if (implementations->didChangeLocationWithinPageForFrameFunc)
534         CallFrameLoadDelegate(implementations->didChangeLocationWithinPageForFrameFunc, webView, @selector(webView:didChangeLocationWithinPageForFrame:), m_webFrame.get());
535 }
536
537 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
538 {
539     WebView *webView = getWebView(m_webFrame.get());
540     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
541     if (implementations->didPushStateWithinPageForFrameFunc)
542         CallFrameLoadDelegate(implementations->didPushStateWithinPageForFrameFunc, webView, @selector(webView:didPushStateWithinPageForFrame:), m_webFrame.get());
543 }
544
545 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
546 {
547     WebView *webView = getWebView(m_webFrame.get());
548     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
549     if (implementations->didReplaceStateWithinPageForFrameFunc)
550         CallFrameLoadDelegate(implementations->didReplaceStateWithinPageForFrameFunc, webView, @selector(webView:didReplaceStateWithinPageForFrame:), m_webFrame.get());
551 }
552
553 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
554 {
555     WebView *webView = getWebView(m_webFrame.get());
556     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
557     if (implementations->didPopStateWithinPageForFrameFunc)
558         CallFrameLoadDelegate(implementations->didPopStateWithinPageForFrameFunc, webView, @selector(webView:didPopStateWithinPageForFrame:), m_webFrame.get());
559 }
560
561 void WebFrameLoaderClient::dispatchWillClose()
562 {
563     WebView *webView = getWebView(m_webFrame.get());   
564     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
565     if (implementations->willCloseFrameFunc)
566         CallFrameLoadDelegate(implementations->willCloseFrameFunc, webView, @selector(webView:willCloseFrame:), m_webFrame.get());
567 }
568
569 void WebFrameLoaderClient::dispatchDidReceiveIcon()
570 {
571 #if ENABLE(ICONDATABASE)
572     WebView *webView = getWebView(m_webFrame.get());   
573     ASSERT(m_webFrame == [webView mainFrame]);
574     [webView _dispatchDidReceiveIconFromWebFrame:m_webFrame.get()];
575 #endif
576 }
577
578 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
579 {
580     WebView *webView = getWebView(m_webFrame.get());   
581     [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
582
583     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
584     if (implementations->didStartProvisionalLoadForFrameFunc)
585         CallFrameLoadDelegate(implementations->didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
586 }
587
588 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
589 {
590     WebView *webView = getWebView(m_webFrame.get());   
591     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
592     if (implementations->didReceiveTitleForFrameFunc)
593         // FIXME: use direction of title.
594         CallFrameLoadDelegate(implementations->didReceiveTitleForFrameFunc, webView, @selector(webView:didReceiveTitle:forFrame:), (NSString *)title.string(), m_webFrame.get());
595 }
596
597 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
598 {
599      // FIXME: Implement this to allow container to update favicon.
600 }
601
602 void WebFrameLoaderClient::dispatchDidCommitLoad()
603 {
604     // Tell the client we've committed this URL.
605     ASSERT([m_webFrame->_private->webFrameView documentView] != nil);
606     
607     WebView *webView = getWebView(m_webFrame.get());   
608     [webView _didCommitLoadForFrame:m_webFrame.get()];
609
610     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
611     if (implementations->didCommitLoadForFrameFunc)
612         CallFrameLoadDelegate(implementations->didCommitLoadForFrameFunc, webView, @selector(webView:didCommitLoadForFrame:), m_webFrame.get());
613 }
614
615 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
616 {
617     WebView *webView = getWebView(m_webFrame.get());   
618     [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
619
620     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
621     if (implementations->didFailProvisionalLoadWithErrorForFrameFunc)
622         CallFrameLoadDelegate(implementations->didFailProvisionalLoadWithErrorForFrameFunc, webView, @selector(webView:didFailProvisionalLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
623
624     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
625 }
626
627 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
628 {
629     WebView *webView = getWebView(m_webFrame.get());   
630     [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
631
632     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
633     if (implementations->didFailLoadWithErrorForFrameFunc)
634         CallFrameLoadDelegate(implementations->didFailLoadWithErrorForFrameFunc, webView, @selector(webView:didFailLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
635
636     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
637 }
638
639 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
640 {
641     WebView *webView = getWebView(m_webFrame.get());
642     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
643     if (implementations->didFinishDocumentLoadForFrameFunc)
644         CallFrameLoadDelegate(implementations->didFinishDocumentLoadForFrameFunc, webView, @selector(webView:didFinishDocumentLoadForFrame:), m_webFrame.get());
645 }
646
647 void WebFrameLoaderClient::dispatchDidFinishLoad()
648 {
649     WebView *webView = getWebView(m_webFrame.get());   
650     [webView _didFinishLoadForFrame:m_webFrame.get()];
651
652     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
653     if (implementations->didFinishLoadForFrameFunc)
654         CallFrameLoadDelegate(implementations->didFinishLoadForFrameFunc, webView, @selector(webView:didFinishLoadForFrame:), m_webFrame.get());
655
656     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
657 }
658
659 void WebFrameLoaderClient::dispatchDidLayout(LayoutMilestones milestones)
660 {
661     WebView *webView = getWebView(m_webFrame.get());
662     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
663
664     if (implementations->didLayoutFunc)
665         CallFrameLoadDelegate(implementations->didLayoutFunc, webView, @selector(webView:didLayout:), kitLayoutMilestones(milestones));
666
667     if (milestones & DidFirstLayout) {
668         // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
669         // new didLayout API.
670         if (implementations->didFirstLayoutInFrameFunc)
671             CallFrameLoadDelegate(implementations->didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
672
673         // See WebFrameLoaderClient::provisionalLoadStarted.
674         WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
675         if ([getWebView(m_webFrame.get()) drawsBackground])
676             [scrollView setDrawsBackground:YES];
677 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
678         [scrollView setVerticalScrollElasticity:NSScrollElasticityAutomatic];
679         [scrollView setHorizontalScrollElasticity:NSScrollElasticityAutomatic];
680 #endif
681     }
682
683     if (milestones & DidFirstVisuallyNonEmptyLayout) {
684         // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
685         // double duty with the new didLayout API.
686         if (implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc)
687             CallFrameLoadDelegate(implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc, webView, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:), m_webFrame.get());
688     }
689 }
690
691 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
692 {
693     WebView *currentWebView = getWebView(m_webFrame.get());
694     NSDictionary *features = [[NSDictionary alloc] init];
695     WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView 
696                                                 createWebViewWithRequest:nil
697                                                           windowFeatures:features];
698     [features release];
699     
700 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
701     if (newWebView)
702         WebKit::NetscapePluginHostManager::shared().didCreateWindow();
703 #endif
704         
705     return core([newWebView mainFrame]);
706 }
707
708 void WebFrameLoaderClient::dispatchShow()
709 {
710     WebView *webView = getWebView(m_webFrame.get());
711     [[webView _UIDelegateForwarder] webViewShow:webView];
712 }
713
714 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function,
715     const ResourceResponse& response, const ResourceRequest& request)
716 {
717     WebView *webView = getWebView(m_webFrame.get());
718
719     [[webView _policyDelegateForwarder] webView:webView
720                         decidePolicyForMIMEType:response.mimeType()
721                                         request:request.nsURLRequest()
722                                           frame:m_webFrame.get()
723                                decisionListener:setUpPolicyListener(function).get()];
724 }
725
726 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
727     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
728 {
729     WebView *webView = getWebView(m_webFrame.get());
730     [[webView _policyDelegateForwarder] webView:webView
731             decidePolicyForNewWindowAction:actionDictionary(action, formState)
732                                    request:request.nsURLRequest()
733                               newFrameName:frameName
734                           decisionListener:setUpPolicyListener(function).get()];
735 }
736
737 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
738     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
739 {
740     WebView *webView = getWebView(m_webFrame.get());
741     [[webView _policyDelegateForwarder] webView:webView
742                 decidePolicyForNavigationAction:actionDictionary(action, formState)
743                                         request:request.nsURLRequest()
744                                           frame:m_webFrame.get()
745                                decisionListener:setUpPolicyListener(function).get()];
746 }
747
748 void WebFrameLoaderClient::cancelPolicyCheck()
749 {
750     [m_policyListener.get() invalidate];
751     m_policyListener = nil;
752     m_policyFunction = 0;
753 }
754
755 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
756 {
757     WebView *webView = getWebView(m_webFrame.get());
758     [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];    
759 }
760
761 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
762 {
763     id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
764     if (!formDelegate) {
765         (core(m_webFrame.get())->loader()->policyChecker()->*function)(PolicyUse);
766         return;
767     }
768
769     const StringPairVector& textFieldValues = formState->textFieldValues();
770     size_t size = textFieldValues.size();
771     NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:size];
772     for (size_t i = 0; i < size; ++i)
773         [dictionary setObject:textFieldValues[i].second forKey:textFieldValues[i].first];
774
775     CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceDocument()->frame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
776
777     [dictionary release];
778 }
779
780 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
781 {
782     [dataSource(loader) _revertToProvisionalState];
783 }
784
785 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
786 {
787     [dataSource(loader) _setMainDocumentError:error];
788 }
789
790 void WebFrameLoaderClient::willChangeEstimatedProgress()
791 {
792     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
793 }
794
795 void WebFrameLoaderClient::didChangeEstimatedProgress()
796 {
797     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
798 }
799
800 void WebFrameLoaderClient::postProgressStartedNotification()
801 {
802     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
803 }
804
805 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
806 {
807     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
808 }
809
810 void WebFrameLoaderClient::postProgressFinishedNotification()
811 {
812     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
813 }
814
815 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
816 {
817     [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
818 }
819
820 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
821 {
822     // FIXME: Should download full request.
823     [getWebView(m_webFrame.get()) _downloadURL:request.url()];
824 }
825
826 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
827 {
828     // FIXME: Should do this only in main frame case, right?
829     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
830 }
831
832 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
833 {
834     // FIXME: Should do this only in main frame case, right?
835     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
836 }
837
838 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
839 {
840     NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
841     [dataSource(loader) _receivedData:nsData];
842     [nsData release];
843 }
844
845 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
846 {
847     [dataSource(loader) _finishedLoading];
848 }
849
850 void WebFrameLoaderClient::updateGlobalHistory()
851 {
852     WebView* view = getWebView(m_webFrame.get());
853     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
854
855     if ([view historyDelegate]) {
856         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
857         if (implementations->navigatedFunc) {
858             WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->urlForHistory()
859                                                                              title:loader->title().string()
860                                                                    originalRequest:loader->originalRequestCopy().nsURLRequest()
861                                                                           response:loader->response().nsURLResponse()
862                                                                  hasSubstituteData:loader->substituteData().isValid()
863                                                               clientRedirectSource:loader->clientRedirectSourceForHistory()];
864
865             CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
866             [data release];
867         }
868     
869         return;
870     }
871
872     [[WebHistory optionalSharedHistory] _visitedURL:loader->urlForHistory() 
873                                           withTitle:loader->title().string()
874                                              method:loader->originalRequestCopy().httpMethod()
875                                          wasFailure:loader->urlForHistoryReflectsFailure()
876                                  increaseVisitCount:!loader->clientRedirectSourceForHistory()]; // Do not increase visit count due to navigations that were not initiated by the user directly, avoiding growth from programmatic reloads.
877 }
878
879 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
880 {
881     WebView* view = getWebView(m_webFrame.get());
882     WebHistoryDelegateImplementationCache* implementations = [view historyDelegate] ? WebViewGetHistoryDelegateImplementations(view) : 0;
883     
884     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
885     ASSERT(loader->unreachableURL().isEmpty());
886
887     if (!loader->clientRedirectSourceForHistory().isNull()) {
888         if (implementations) {
889             if (implementations->clientRedirectFunc) {
890                 CallHistoryDelegate(implementations->clientRedirectFunc, view, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:), 
891                     loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_webFrame.get());
892             }
893         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->clientRedirectSourceForHistory()])
894             core(item)->addRedirectURL(loader->clientRedirectDestinationForHistory());
895     }
896
897     if (!loader->serverRedirectSourceForHistory().isNull()) {
898         if (implementations) {
899             if (implementations->serverRedirectFunc) {
900                 CallHistoryDelegate(implementations->serverRedirectFunc, view, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:), 
901                     loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_webFrame.get());
902             }
903         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->serverRedirectSourceForHistory()])
904             core(item)->addRedirectURL(loader->serverRedirectDestinationForHistory());
905     }
906 }
907
908 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
909 {
910     WebView* view = getWebView(m_webFrame.get());
911     WebHistoryItem *webItem = kit(item);
912     
913     return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
914 }
915
916 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
917 {
918     return true;
919 }
920
921 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
922 {
923     HistoryItem* historyItem = 0;
924
925     if (Page* page = core(m_webFrame.get())->page()) {
926         if (!page->settings()->privateBrowsingEnabled())
927             historyItem = page->backForward()->currentItem();
928     }
929
930     WebView *webView = getWebView(m_webFrame.get());
931     [webView _setGlobalHistoryItem:historyItem];
932 }
933
934 void WebFrameLoaderClient::didDisplayInsecureContent()
935 {
936     WebView *webView = getWebView(m_webFrame.get());   
937     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
938     if (implementations->didDisplayInsecureContentFunc)
939         CallFrameLoadDelegate(implementations->didDisplayInsecureContentFunc, webView, @selector(webViewDidDisplayInsecureContent:));
940 }
941
942 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
943 {
944     WebView *webView = getWebView(m_webFrame.get());   
945     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
946     if (implementations->didRunInsecureContentFunc) {
947         RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin]);
948         CallFrameLoadDelegate(implementations->didRunInsecureContentFunc, webView, @selector(webView:didRunInsecureContent:), webSecurityOrigin.get());
949     }
950 }
951
952 void WebFrameLoaderClient::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
953 {
954     WebView *webView = getWebView(m_webFrame.get());   
955     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
956     if (implementations->didDetectXSSFunc) {
957         // FIXME: must pass didBlockEntirePage if we want to do more on mac than just pass tests.
958         NSURL* insecureNSURL = insecureURL;
959         CallFrameLoadDelegate(implementations->didDetectXSSFunc, webView, @selector(webView:didDetectXSS:), insecureNSURL);
960     }
961 }
962
963 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
964 {
965     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()];
966 }
967     
968 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
969 {
970     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()];
971 }
972
973 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
974 {
975     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()];
976 }
977
978 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
979 {
980     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
981 }
982
983 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
984 {
985     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
986 }
987
988 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
989 {
990     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()];    
991 }
992
993 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
994 {
995     NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
996                                                     contentURL:response.url()
997                                                  pluginPageURL:nil
998                                                     pluginName:nil
999                                                       MIMEType:response.mimeType()];
1000     return [error autorelease];
1001 }
1002
1003 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1004 {
1005     // FIXME: Needs to check domain.
1006     // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
1007     // loading plugin content twice.  See <rdar://problem/4258008>
1008     return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
1009 }
1010
1011 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
1012 {
1013     Frame* frame = core(m_webFrame.get());
1014     Page* page = frame->page();
1015     BOOL forMainFrame = page && page->mainFrame() == frame;
1016     return [WebView _canHandleRequest:request.nsURLRequest() forMainFrame:forMainFrame];
1017 }
1018
1019 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1020 {
1021     return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType];
1022 }
1023
1024 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1025 {
1026     return [WebView canShowMIMETypeAsHTML:MIMEType];
1027 }
1028
1029 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1030 {
1031     return [WebView _representationExistsForURLScheme:URLScheme];
1032 }
1033
1034 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1035 {
1036     return [WebView _generatedMIMETypeForURLScheme:URLScheme];
1037 }
1038
1039 void WebFrameLoaderClient::frameLoadCompleted()
1040 {
1041     // Note: Can be called multiple times.
1042
1043     // See WebFrameLoaderClient::provisionalLoadStarted.
1044     if ([getWebView(m_webFrame.get()) drawsBackground])
1045         [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:YES];
1046 }
1047
1048 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* item)
1049 {
1050     if (!item)
1051         return;
1052     
1053     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1054
1055     // we might already be detached when this is called from detachFromParent, in which
1056     // case we don't want to override real data earlier gathered with (0,0)
1057     if ([docView superview] && [docView conformsToProtocol:@protocol(_WebDocumentViewState)])
1058         item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
1059 }
1060
1061 void WebFrameLoaderClient::restoreViewState()
1062 {
1063     HistoryItem* currentItem = core(m_webFrame.get())->loader()->history()->currentItem();
1064     ASSERT(currentItem);
1065
1066     // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
1067     // One counterexample is <rdar://problem/4917290>
1068     // For now, to cover this issue in release builds, there is no technical harm to returning
1069     // early and from a user standpoint - as in the above radar - the previous page load failed 
1070     // so there *is* no scroll state to restore!
1071     if (!currentItem)
1072         return;
1073     
1074     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1075     if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {        
1076         id state = currentItem->viewState();
1077         if (state) {
1078             [(id <_WebDocumentViewState>)docView setViewState:state];
1079         }
1080     }
1081 }
1082
1083 void WebFrameLoaderClient::provisionalLoadStarted()
1084 {    
1085     // Tell the scroll view not to draw a background so we can leave the contents of
1086     // the old page showing during the beginning of the loading process.
1087
1088     // This will stay set to NO until:
1089     //    1) The load gets far enough along: WebFrameLoader::frameLoadCompleted.
1090     //    2) The window is resized: -[WebFrameView setFrameSize:].
1091     // or 3) The view is moved out of the window: -[WebFrameView viewDidMoveToWindow].
1092     // Please keep the comments in these four functions in agreement with each other.
1093
1094     WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
1095     [scrollView setDrawsBackground:NO];
1096 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
1097     [scrollView setVerticalScrollElasticity:NSScrollElasticityNone];
1098     [scrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
1099 #endif
1100 }
1101
1102 void WebFrameLoaderClient::didFinishLoad()
1103 {
1104     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];    
1105 }
1106
1107 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1108 {
1109     if (![m_webFrame.get() _dataSource]) {
1110         ASSERT(!core(m_webFrame.get())->tree()->childCount());
1111         return;
1112     }
1113     
1114     // Make sure that any work that is triggered by resigning first reponder can get done.
1115     // The main example where this came up is the textDidEndEditing that is sent to the
1116     // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
1117     // remove the views as a side-effect of freeing the frame, at which point we can't
1118     // post the FormDelegate messages.
1119     //
1120     // Note that this can also take FirstResponder away from a child of our frameView that
1121     // is not in a child frame's view.  This is OK because we are in the process
1122     // of loading new content, which will blow away all editors in this top frame, and if
1123     // a non-editor is firstReponder it will not be affected by endEditingFor:.
1124     // Potentially one day someone could write a DocView whose editors were not all
1125     // replaced by loading new content, but that does not apply currently.
1126     NSView *frameView = m_webFrame->_private->webFrameView;
1127     NSWindow *window = [frameView window];
1128     NSResponder *firstResp = [window firstResponder];
1129     if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
1130         [window endEditingFor:firstResp];
1131 }
1132
1133 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1134 {
1135     RefPtr<WebDocumentLoaderMac> loader = WebDocumentLoaderMac::create(request, substituteData);
1136
1137     WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
1138     loader->setDataSource(dataSource, getWebView(m_webFrame.get()));
1139     [dataSource release];
1140
1141     return loader.release();
1142 }
1143
1144 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1145 {
1146     WebView* view = getWebView(m_webFrame.get());
1147     
1148     if ([view historyDelegate]) {
1149         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
1150         if (!implementations->setTitleFunc)
1151             return;
1152             
1153         // FIXME: use direction of title.
1154         CallHistoryDelegate(implementations->setTitleFunc, view, @selector(webView:updateHistoryTitle:forURL:), (NSString *)title.string(), (NSString *)url);
1155         return;
1156     }
1157     
1158     NSURL* nsURL = url;
1159     nsURL = [nsURL _webkit_canonicalize];
1160     if(!nsURL)
1161         return;
1162     NSString *titleNSString = title.string();
1163        
1164     [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
1165 }
1166
1167 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1168 {
1169     OwnPtr<WebCachedFramePlatformData> webPlatformData = adoptPtr(new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]));
1170     cachedFrame->setCachedFramePlatformData(webPlatformData.release());
1171 }
1172
1173 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
1174 {
1175     WebCachedFramePlatformData* platformData = reinterpret_cast<WebCachedFramePlatformData*>(cachedFrame->cachedFramePlatformData());
1176     NSView <WebDocumentView> *cachedView = platformData->webDocumentView();
1177     ASSERT(cachedView != nil);
1178     ASSERT(cachedFrame->documentLoader());
1179     [cachedView setDataSource:dataSource(cachedFrame->documentLoader())];
1180     
1181     // clean up webkit plugin instances before WebHTMLView gets freed.
1182     WebView *webView = getWebView(m_webFrame.get());
1183     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1184     
1185     [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
1186 }
1187
1188 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1189 {
1190     WebView *webView = getWebView(m_webFrame.get());
1191     WebDataSource *dataSource = [m_webFrame.get() _dataSource];
1192
1193     bool willProduceHTMLView = [m_webFrame->_private->webFrameView _viewClassForMIMEType:[dataSource _responseMIMEType]] == [WebHTMLView class];
1194     bool canSkipCreation = core(m_webFrame.get())->loader()->stateMachine()->committingFirstRealLoad() && willProduceHTMLView;
1195     if (canSkipCreation) {
1196         [[m_webFrame->_private->webFrameView documentView] setDataSource:dataSource];
1197         return;
1198     }
1199
1200     // Don't suppress scrollbars before the view creation if we're making the view for a non-HTML view.
1201     if (!willProduceHTMLView)
1202         [[m_webFrame->_private->webFrameView _scrollView] setScrollBarsSuppressed:NO repaintOnUnsuppress:NO];
1203     
1204     // clean up webkit plugin instances before WebHTMLView gets freed.
1205     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1206     
1207     NSView <WebDocumentView> *documentView = [m_webFrame->_private->webFrameView _makeDocumentViewForDataSource:dataSource];
1208     if (!documentView)
1209         return;
1210
1211     // FIXME: Could we skip some of this work for a top-level view that is not a WebHTMLView?
1212
1213     // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
1214     Frame* coreFrame = core(m_webFrame.get());
1215     Page* page = coreFrame->page();
1216     bool isMainFrame = coreFrame == page->mainFrame();
1217     if (isMainFrame && coreFrame->view())
1218         coreFrame->view()->setParentVisible(false);
1219     coreFrame->setView(0);
1220     RefPtr<FrameView> coreView = FrameView::create(coreFrame);
1221     coreFrame->setView(coreView);
1222
1223     [m_webFrame.get() _updateBackgroundAndUpdatesWhileOffscreen];
1224     [m_webFrame->_private->webFrameView _install];
1225
1226     if (isMainFrame)
1227         coreView->setParentVisible(true);
1228
1229     // Call setDataSource on the document view after it has been placed in the view hierarchy.
1230     // This what we for the top-level view, so should do this for views in subframes as well.
1231     [documentView setDataSource:dataSource];
1232
1233     // The following is a no-op for WebHTMLRepresentation, but for custom document types
1234     // like the ones that Safari uses for bookmarks it is the only way the DocumentLoader
1235     // will get the proper title.
1236     if (DocumentLoader* documentLoader = [dataSource _documentLoader])
1237         documentLoader->setTitle(StringWithDirection([dataSource pageTitle], LTR));
1238
1239     if (HTMLFrameOwnerElement* owner = coreFrame->ownerElement())
1240         coreFrame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
1241         
1242     // If the document view implicitly became first responder, make sure to set the focused frame properly.
1243     if ([[documentView window] firstResponder] == documentView) {
1244         page->focusController()->setFocusedFrame(coreFrame);
1245         page->focusController()->setFocused(true);
1246     }
1247 }
1248
1249 void WebFrameLoaderClient::didSaveToPageCache()
1250 {
1251 }
1252
1253 void WebFrameLoaderClient::didRestoreFromPageCache()
1254 {
1255 }
1256
1257 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1258 {
1259 }
1260
1261 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
1262 {
1263     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1264
1265     [m_policyListener.get() invalidate];
1266
1267     WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
1268     m_policyListener = listener;
1269     [listener release];
1270     m_policyFunction = function;
1271
1272     return listener;
1273 }
1274
1275 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1276 {
1277     ASSERT(m_policyListener);
1278     ASSERT(m_policyFunction);
1279
1280     FramePolicyFunction function = m_policyFunction;
1281
1282     m_policyListener = nil;
1283     m_policyFunction = 0;
1284
1285     (core(m_webFrame.get())->loader()->policyChecker()->*function)(action);
1286 }
1287
1288 String WebFrameLoaderClient::userAgent(const KURL& url)
1289 {
1290     WebView *webView = getWebView(m_webFrame.get());
1291     ASSERT(webView);
1292
1293     // We should never get here with nil for the WebView unless there is a bug somewhere else.
1294     // But if we do, it's better to return the empty string than just crashing on the spot.
1295     // Most other call sites are tolerant of nil because of Objective-C behavior, but this one
1296     // is not because the return value of _userAgentForURL is a const KURL&.
1297     if (!webView)
1298         return String("");
1299
1300     return [webView _userAgentString];
1301 }
1302
1303 static const MouseEvent* findMouseEvent(const Event* event)
1304 {
1305     for (const Event* e = event; e; e = e->underlyingEvent())
1306         if (e->isMouseEvent())
1307             return static_cast<const MouseEvent*>(e);
1308     return 0;
1309 }
1310
1311 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action, PassRefPtr<FormState> formState) const
1312 {
1313     unsigned modifierFlags = 0;
1314     const Event* event = action.event();
1315     if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1316         if (keyStateEvent->ctrlKey())
1317             modifierFlags |= NSControlKeyMask;
1318         if (keyStateEvent->altKey())
1319             modifierFlags |= NSAlternateKeyMask;
1320         if (keyStateEvent->shiftKey())
1321             modifierFlags |= NSShiftKeyMask;
1322         if (keyStateEvent->metaKey())
1323             modifierFlags |= NSCommandKeyMask;
1324     }
1325
1326     NSURL *originalURL = action.url();
1327
1328     NSMutableDictionary *result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
1329         [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1330         [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1331         originalURL, WebActionOriginalURLKey,
1332         nil];
1333
1334     if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1335         WebElementDictionary *element = [[WebElementDictionary alloc]
1336             initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)];
1337         [result setObject:element forKey:WebActionElementKey];
1338         [element release];
1339
1340         [result setObject:[NSNumber numberWithInt:mouseEvent->button()] forKey:WebActionButtonKey];
1341     }
1342
1343     if (formState) {
1344         ASSERT(formState->form());
1345         [result setObject:kit(formState->form()) forKey:WebActionFormKey];
1346     }
1347
1348     return result;
1349 }
1350
1351 bool WebFrameLoaderClient::canCachePage() const
1352 {
1353     // We can only cache HTML pages right now
1354     return [[[m_webFrame.get() _dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1355 }
1356
1357 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1358     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1359 {
1360     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1361     
1362     ASSERT(m_webFrame);
1363     
1364     WebFrameView *childView = [[WebFrameView alloc] init];
1365     
1366     RefPtr<Frame> result = [WebFrame _createSubframeWithOwnerElement:ownerElement frameName:name frameView:childView];
1367     [childView release];
1368
1369     WebFrame *newFrame = kit(result.get());
1370
1371     if ([newFrame _dataSource])
1372         [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding());  
1373
1374     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1375     if (!result->page())
1376         return 0;
1377  
1378     core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, result.get());
1379
1380     // The frame's onload handler may have removed it from the document.
1381     if (!result->tree()->parent())
1382         return 0;
1383
1384     return result.release();
1385
1386     END_BLOCK_OBJC_EXCEPTIONS;
1387
1388     return 0;
1389 }
1390
1391 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1392 {
1393     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1394
1395     String type = mimeType;
1396
1397     if (type.isEmpty()) {
1398         // Try to guess the MIME type based off the extension.
1399         NSURL *URL = url;
1400         NSString *extension = [[URL path] pathExtension];
1401         if ([extension length] > 0) {
1402             type = WKGetMIMETypeForExtension(extension);
1403             if (type.isEmpty()) {
1404                 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
1405                 if (WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForExtension:extension]) {
1406                     if ([package isKindOfClass:[WebPluginPackage class]]) 
1407                         return ObjectContentOtherPlugin;
1408 #if ENABLE(NETSCAPE_PLUGIN_API)
1409                     else {
1410                         ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
1411                         return ObjectContentNetscapePlugin;
1412                     }
1413 #endif
1414                 }
1415             }
1416         }
1417     }
1418
1419     if (type.isEmpty())
1420         return ObjectContentFrame; // Go ahead and hope that we can display the content.
1421
1422     WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForMIMEType:type];
1423     ObjectContentType plugInType = ObjectContentNone;
1424     if (package) {
1425 #if ENABLE(NETSCAPE_PLUGIN_API)
1426         if ([package isKindOfClass:[WebNetscapePluginPackage class]])
1427             plugInType = ObjectContentNetscapePlugin;
1428         else
1429 #endif
1430         {
1431             ASSERT([package isKindOfClass:[WebPluginPackage class]]);
1432             plugInType = ObjectContentOtherPlugin;
1433         }
1434     }
1435     
1436     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
1437         return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
1438
1439     if (plugInType != ObjectContentNone)
1440         return plugInType;
1441
1442     if ([m_webFrame->_private->webFrameView _viewClassForMIMEType:type])
1443         return ObjectContentFrame;
1444     
1445     return ObjectContentNone;
1446
1447     END_BLOCK_OBJC_EXCEPTIONS;
1448
1449     return ObjectContentNone;
1450 }
1451
1452 static NSMutableArray* kit(const Vector<String>& vector)
1453 {
1454     unsigned len = vector.size();
1455     NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1456     for (unsigned x = 0; x < len; x++)
1457         [array addObject:vector[x]];
1458     return array;
1459 }
1460
1461 static String parameterValue(const Vector<String>& paramNames, const Vector<String>& paramValues, const String& name)
1462 {
1463     size_t size = paramNames.size();
1464     ASSERT(size == paramValues.size());
1465     for (size_t i = 0; i < size; ++i) {
1466         if (equalIgnoringCase(paramNames[i], name))
1467             return paramValues[i];
1468     }
1469     return String();
1470 }
1471
1472 static NSView *pluginView(WebFrame *frame, WebPluginPackage *pluginPackage,
1473     NSArray *attributeNames, NSArray *attributeValues, NSURL *baseURL,
1474     DOMElement *element, BOOL loadManually)
1475 {
1476     WebHTMLView *docView = (WebHTMLView *)[[frame frameView] documentView];
1477     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1478         
1479     WebPluginController *pluginController = [docView _pluginController];
1480     
1481     // Store attributes in a dictionary so they can be passed to WebPlugins.
1482     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
1483     
1484     [pluginPackage load];
1485     Class viewFactory = [pluginPackage viewFactory];
1486     
1487     NSView *view = nil;
1488     NSDictionary *arguments = nil;
1489     
1490     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
1491         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1492             baseURL, WebPlugInBaseURLKey,
1493             attributes, WebPlugInAttributesKey,
1494             pluginController, WebPlugInContainerKey,
1495             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1496             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1497             element, WebPlugInContainingElementKey,
1498             nil];
1499         LOG(Plugins, "arguments:\n%@", arguments);
1500     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
1501         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1502             baseURL, WebPluginBaseURLKey,
1503             attributes, WebPluginAttributesKey,
1504             pluginController, WebPluginContainerKey,
1505             element, WebPlugInContainingElementKey,
1506             nil];
1507         LOG(Plugins, "arguments:\n%@", arguments);
1508     }
1509
1510     view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
1511     [attributes release];
1512     return view;
1513 }
1514
1515 class PluginWidget : public PluginViewBase {
1516 public:
1517     PluginWidget(NSView *view = 0)
1518         : PluginViewBase(view)
1519     {
1520     }
1521     
1522 private:
1523     virtual void invalidateRect(const IntRect& rect)
1524     {
1525         [platformWidget() setNeedsDisplayInRect:rect];
1526     }
1527 };
1528
1529 #if ENABLE(NETSCAPE_PLUGIN_API)
1530
1531 class NetscapePluginWidget : public PluginWidget {
1532 public:
1533     NetscapePluginWidget(WebBaseNetscapePluginView *view)
1534         : PluginWidget(view)
1535     {
1536     }
1537     
1538 #if USE(ACCELERATED_COMPOSITING)
1539     virtual PlatformLayer* platformLayer() const
1540     {
1541         return [(WebBaseNetscapePluginView *)platformWidget() pluginLayer];
1542     }
1543 #endif
1544
1545     virtual bool getFormValue(String& value)
1546     {
1547         NSString* nsValue = 0;
1548         if ([(WebBaseNetscapePluginView *)platformWidget() getFormValue:&nsValue]) {
1549             if (!nsValue)
1550                 return false;
1551             value = String(nsValue);
1552             [nsValue release];
1553             return true;
1554         }
1555         return false;
1556     }
1557
1558     virtual void handleEvent(Event* event)
1559     {
1560         Frame* frame = Frame::frameForWidget(this);
1561         if (!frame)
1562             return;
1563         
1564         NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
1565         if (event->type() == eventNames().mousemoveEvent)
1566             [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
1567         else if (event->type() == eventNames().mouseoverEvent)
1568             [(WebBaseNetscapePluginView *)platformWidget() handleMouseEntered:currentNSEvent];
1569         else if (event->type() == eventNames().mouseoutEvent)
1570             [(WebBaseNetscapePluginView *)platformWidget() handleMouseExited:currentNSEvent];
1571         else if (event->type() == eventNames().contextmenuEvent)
1572             event->setDefaultHandled(); // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one.
1573     }
1574
1575 private:
1576     virtual void notifyWidget(WidgetNotification notification)
1577     {
1578         switch (notification) {
1579         case WillPaintFlattened: {
1580             BEGIN_BLOCK_OBJC_EXCEPTIONS;
1581             [(WebBaseNetscapePluginView *)platformWidget() cacheSnapshot];
1582             END_BLOCK_OBJC_EXCEPTIONS;
1583             break;
1584         }
1585         case DidPaintFlattened: {
1586             BEGIN_BLOCK_OBJC_EXCEPTIONS;
1587             [(WebBaseNetscapePluginView *)platformWidget() clearCachedSnapshot];
1588             END_BLOCK_OBJC_EXCEPTIONS;
1589             break;
1590         }
1591         }
1592     }
1593 };
1594
1595 #if USE(PLUGIN_HOST_PROCESS)
1596 #define NETSCAPE_PLUGIN_VIEW WebHostedNetscapePluginView
1597 #else
1598 #define NETSCAPE_PLUGIN_VIEW WebNetscapePluginView
1599 #endif
1600
1601 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1602
1603 static bool isOracleJavaPlugIn(NSString *bundleIdentifier)
1604 {
1605     return [bundleIdentifier isEqualToString:@"com.oracle.java.JavaAppletPlugin"];
1606 }
1607
1608 static bool isPlugInInactive(NSString *bundleIdentifier)
1609 {
1610     if (isOracleJavaPlugIn(bundleIdentifier) && !WKIsJavaPlugInActive())
1611         return true;
1612
1613     return false;
1614 }
1615
1616 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& size, HTMLPlugInElement* element, const KURL& url,
1617     const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1618 {
1619     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1620
1621     ASSERT(paramNames.size() == paramValues.size());
1622
1623     int errorCode = 0;
1624
1625     WebView *webView = getWebView(m_webFrame.get());
1626     SEL selector = @selector(webView:plugInViewWithArguments:);
1627
1628     Document* document = core(m_webFrame.get())->document();
1629     NSURL *baseURL = document->baseURL();
1630     NSURL *pluginURL = url;
1631     
1632     // <rdar://problem/8366089>: AppleConnect has a bug where it does not
1633     // understand the parameter names specified in the <object> element that
1634     // embeds its plug-in. This site-specific hack works around the issue by
1635     // converting the parameter names to lowercase before passing them to the
1636     // plug-in.
1637     Frame* frame = core(m_webFrame.get());
1638     NSMutableArray *attributeKeys = kit(paramNames);
1639     if (frame && frame->settings()->needsSiteSpecificQuirks() && equalIgnoringCase(mimeType, "application/x-snkp")) {
1640         for (NSUInteger i = 0; i < [attributeKeys count]; ++i)
1641             [attributeKeys replaceObjectAtIndex:i withObject:[[attributeKeys objectAtIndex:i] lowercaseString]];
1642     }
1643     
1644     if ([[webView UIDelegate] respondsToSelector:selector]) {
1645         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:attributeKeys];
1646         NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1647             attributes, WebPlugInAttributesKey,
1648             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1649             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1650             kit(element), WebPlugInContainingElementKey,
1651             // FIXME: We should be passing base URL, see <https://bugs.webkit.org/show_bug.cgi?id=35215>.
1652             pluginURL, WebPlugInBaseURLKey, // pluginURL might be nil, so add it last
1653             nil];
1654
1655         NSView *view = CallUIDelegate(webView, selector, arguments);
1656
1657         [attributes release];
1658         [arguments release];
1659
1660         if (view)
1661             return adoptRef(new PluginWidget(view));
1662     }
1663
1664     NSString *MIMEType;
1665     WebBasePluginPackage *pluginPackage;
1666     if (mimeType.isEmpty()) {
1667         MIMEType = nil;
1668         pluginPackage = nil;
1669     } else {
1670         MIMEType = mimeType;
1671         pluginPackage = [webView _pluginForMIMEType:mimeType];
1672     }
1673     
1674     NSString *extension = [[pluginURL path] pathExtension];
1675     if (!pluginPackage && [extension length] && ![MIMEType length]) {
1676         pluginPackage = [webView _pluginForExtension:extension];
1677         if (pluginPackage) {
1678             NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
1679             if ([newMIMEType length] != 0)
1680                 MIMEType = newMIMEType;
1681         }
1682     }
1683
1684     NSView *view = nil;
1685
1686     if (pluginPackage) {
1687         if (WKShouldBlockPlugin([pluginPackage bundleIdentifier], [pluginPackage bundleVersion])) {
1688             errorCode = WebKitErrorBlockedPlugInVersion;
1689             if (element->renderer()->isEmbeddedObject())
1690                 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
1691         } else if (isPlugInInactive([pluginPackage bundleIdentifier])) {
1692             if (element->renderer()->isEmbeddedObject())
1693                 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginInactive);
1694             return 0;
1695         } else {
1696             if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1697                 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, attributeKeys, kit(paramValues), baseURL, kit(element), loadManually);
1698
1699 #if ENABLE(NETSCAPE_PLUGIN_API)
1700             else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1701                 WebBaseNetscapePluginView *pluginView = [[[NETSCAPE_PLUGIN_VIEW alloc]
1702                     initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1703                     pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1704                     URL:pluginURL
1705                     baseURL:baseURL
1706                     MIMEType:MIMEType
1707                     attributeKeys:attributeKeys
1708                     attributeValues:kit(paramValues)
1709                     loadManually:loadManually
1710                     element:element] autorelease];
1711
1712                 return adoptRef(new NetscapePluginWidget(pluginView));
1713             }
1714 #endif
1715         }
1716     } else
1717         errorCode = WebKitErrorCannotFindPlugIn;
1718
1719     if (!errorCode && !view)
1720         errorCode = WebKitErrorCannotLoadPlugIn;
1721     
1722     if (errorCode && m_webFrame) {
1723         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
1724         if (implementations->plugInFailedWithErrorFunc) {
1725             KURL pluginPageURL = document->completeURL(stripLeadingAndTrailingHTMLSpaces(parameterValue(paramNames, paramValues, "pluginspage")));
1726             if (!pluginPageURL.protocolIsInHTTPFamily())
1727                 pluginPageURL = KURL();
1728             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1729
1730             NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1731                                                             contentURL:pluginURL pluginPageURL:pluginPageURL pluginName:pluginName MIMEType:MIMEType];
1732             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1733                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1734             [error release];
1735         }
1736
1737         return 0;
1738     }
1739     
1740     ASSERT(view);
1741     return adoptRef(new PluginWidget(view));
1742
1743     END_BLOCK_OBJC_EXCEPTIONS;
1744
1745     return 0;
1746 }
1747
1748 void WebFrameLoaderClient::recreatePlugin(Widget*)
1749 {
1750 }
1751
1752 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1753 {
1754     if (!pluginWidget)
1755         return;
1756
1757     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1758
1759     WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[m_webFrame.get() _dataSource] representation];
1760
1761     NSView *pluginView = pluginWidget->platformWidget();
1762
1763 #if ENABLE(NETSCAPE_PLUGIN_API)
1764     if ([pluginView isKindOfClass:[NETSCAPE_PLUGIN_VIEW class]])
1765         [representation _redirectDataToManualLoader:(NETSCAPE_PLUGIN_VIEW *)pluginView forPluginView:pluginView];
1766     else {
1767 #else
1768     {
1769 #endif
1770         WebHTMLView *documentView = (WebHTMLView *)[[m_webFrame.get() frameView] documentView];
1771         ASSERT([documentView isKindOfClass:[WebHTMLView class]]);
1772         [representation _redirectDataToManualLoader:[documentView _pluginController] forPluginView:pluginView];
1773     }
1774
1775     END_BLOCK_OBJC_EXCEPTIONS;
1776 }
1777     
1778 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const KURL& baseURL, 
1779     const Vector<String>& paramNames, const Vector<String>& paramValues)
1780 {
1781     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1782
1783     NSView *view = nil;
1784
1785     NSString *MIMEType = @"application/x-java-applet";
1786     
1787     WebView *webView = getWebView(m_webFrame.get());
1788
1789     WebBasePluginPackage *pluginPackage = [webView _pluginForMIMEType:MIMEType];
1790
1791     int errorCode = WebKitErrorJavaUnavailable;
1792
1793     if (pluginPackage) {
1794         if (WKShouldBlockPlugin([pluginPackage bundleIdentifier], [pluginPackage bundleVersion])) {
1795             errorCode = WebKitErrorBlockedPlugInVersion;
1796             if (element->renderer()->isEmbeddedObject())
1797                 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
1798         } else if (isPlugInInactive([pluginPackage bundleIdentifier])) {
1799             if (element->renderer()->isEmbeddedObject())
1800                 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginInactive);
1801             return 0;
1802         } else {
1803     #if ENABLE(NETSCAPE_PLUGIN_API)
1804             if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1805                 view = [[[NETSCAPE_PLUGIN_VIEW alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1806                     pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1807                     URL:nil
1808                     baseURL:baseURL
1809                     MIMEType:MIMEType
1810                     attributeKeys:kit(paramNames)
1811                     attributeValues:kit(paramValues)
1812                     loadManually:NO
1813                     element:element] autorelease];
1814                 if (view)
1815                     return adoptRef(new NetscapePluginWidget(static_cast<WebBaseNetscapePluginView *>(view)));
1816             }
1817     #endif
1818         }
1819     }
1820
1821     if (!view) {
1822         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(getWebView(m_webFrame.get()));
1823         if (implementations->plugInFailedWithErrorFunc) {
1824             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1825             NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode contentURL:nil pluginPageURL:nil pluginName:pluginName MIMEType:MIMEType];
1826             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1827                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1828             [error release];
1829         }
1830     }
1831
1832     END_BLOCK_OBJC_EXCEPTIONS;
1833
1834     return 0;
1835 }
1836
1837 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1838 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize& size, HTMLMediaElement* element, const KURL& url,
1839     const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType)
1840 {
1841     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1842
1843     ASSERT(paramNames.size() == paramValues.size());
1844     ASSERT(mimeType);
1845
1846     int errorCode = 0;
1847     WebView *webView = getWebView(m_webFrame.get());
1848     NSURL *URL = url;
1849
1850     SEL selector = @selector(webView:plugInViewWithArguments:);
1851
1852     if ([[webView UIDelegate] respondsToSelector:selector]) {
1853         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:kit(paramNames)];
1854         NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1855             attributes, WebPlugInAttributesKey,
1856             [NSNumber numberWithInt:WebPlugInModeEmbed], WebPlugInModeKey,
1857             [NSNumber numberWithBool:YES], WebPlugInShouldLoadMainResourceKey,
1858             kit(element), WebPlugInContainingElementKey,
1859             URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
1860             nil];
1861
1862         NSView *view = CallUIDelegate(webView, selector, arguments);
1863
1864         [attributes release];
1865         [arguments release];
1866
1867         if (view)
1868             return adoptRef(new PluginWidget(view));
1869     }
1870
1871     WebBasePluginPackage *pluginPackage = [webView _videoProxyPluginForMIMEType:mimeType];
1872     Document* document = core(m_webFrame.get())->document();
1873     NSURL *baseURL = document->baseURL();
1874     NSView *view = nil;
1875
1876     if (pluginPackage) {
1877         if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1878             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, kit(paramNames), kit(paramValues), baseURL, kit(element), false);
1879     } else
1880         errorCode = WebKitErrorCannotFindPlugIn;
1881
1882     if (!errorCode && !view)
1883         errorCode = WebKitErrorCannotLoadPlugIn;
1884
1885     if (errorCode) {
1886         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1887             contentURL:URL pluginPageURL:nil pluginName:[pluginPackage pluginInfo].name MIMEType:mimeType];
1888         WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1889             error:error DOMElement:kit(element)] autorelease];
1890         view = nullView;
1891         [error release];
1892     }
1893     
1894     ASSERT(view);
1895     return adoptRef(new PluginWidget(view));
1896
1897     END_BLOCK_OBJC_EXCEPTIONS;
1898
1899     return 0;
1900 }
1901
1902 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget)
1903 {
1904     [WebPluginController pluginViewHidden:widget->platformWidget()];
1905 }
1906
1907 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget)
1908 {
1909     [WebPluginController addPlugInView:widget->platformWidget()];
1910 }
1911
1912 #endif  // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1913
1914 String WebFrameLoaderClient::overrideMediaType() const
1915 {
1916     NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle];
1917     if (overrideType)
1918         return overrideType;
1919     return String();
1920 }
1921
1922 void WebFrameLoaderClient::documentElementAvailable() {
1923 }
1924
1925 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1926 {
1927     WebView *webView = getWebView(m_webFrame.get());
1928     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1929
1930     if (implementations->didClearWindowObjectForFrameInScriptWorldFunc) {
1931         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameInScriptWorldFunc,
1932             webView, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:), m_webFrame.get(), [WebScriptWorld findOrCreateWorld:world]);
1933         return;
1934     }
1935
1936     if (world != mainThreadNormalWorld())
1937         return;
1938
1939     Frame *frame = core(m_webFrame.get());
1940     ScriptController *script = frame->script();
1941
1942     if (implementations->didClearWindowObjectForFrameFunc) {
1943         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:),
1944             script->windowScriptObject(), m_webFrame.get());
1945     } else if (implementations->windowScriptObjectAvailableFunc) {
1946         CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:),
1947             script->windowScriptObject());
1948     }
1949
1950     if ([webView scriptDebugDelegate]) {
1951         [m_webFrame.get() _detachScriptDebugger];
1952         [m_webFrame.get() _attachScriptDebugger];
1953     }
1954 }
1955
1956 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1957 {
1958 #if ENABLE(ICONDATABASE)
1959     [[m_webFrame.get() webView] _registerForIconNotification:listen];
1960 #endif
1961 }
1962
1963 void WebFrameLoaderClient::didPerformFirstNavigation() const
1964 {
1965     WebPreferences *preferences = [[m_webFrame.get() webView] preferences];
1966     if ([preferences automaticallyDetectsCacheModel] && [preferences cacheModel] < WebCacheModelDocumentBrowser)
1967         [preferences setCacheModel:WebCacheModelDocumentBrowser];
1968 }
1969
1970 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1971 {
1972     return WebFrameNetworkingContext::create(core(m_webFrame.get()));
1973 }
1974
1975 @implementation WebFramePolicyListener
1976 + (void)initialize
1977 {
1978     JSC::initializeThreading();
1979     WTF::initializeMainThreadToProcessMainThread();
1980     WebCore::RunLoop::initializeMainRunLoop();
1981     WebCoreObjCFinalizeOnMainThread(self);
1982 }
1983
1984 - (id)initWithWebCoreFrame:(Frame*)frame
1985 {
1986     self = [self init];
1987     if (!self)
1988         return nil;
1989     frame->ref();
1990     m_frame = frame;
1991     return self;
1992 }
1993
1994 - (void)invalidate
1995 {
1996     if (m_frame) {
1997         m_frame->deref();
1998         m_frame = 0;
1999     }
2000 }
2001
2002 - (void)dealloc
2003 {
2004     if (WebCoreObjCScheduleDeallocateOnMainThread([WebFramePolicyListener class], self))
2005         return;
2006
2007     if (m_frame)
2008         m_frame->deref();
2009     [super dealloc];
2010 }
2011
2012 - (void)finalize
2013 {
2014     ASSERT_MAIN_THREAD();
2015     if (m_frame)
2016         m_frame->deref();
2017     [super finalize];
2018 }
2019
2020 - (void)receivedPolicyDecision:(PolicyAction)action
2021 {
2022     RefPtr<Frame> frame = adoptRef(m_frame);
2023     m_frame = 0;
2024     if (frame)
2025         static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
2026 }
2027
2028 - (void)ignore
2029 {
2030     [self receivedPolicyDecision:PolicyIgnore];
2031 }
2032
2033 - (void)download
2034 {
2035     [self receivedPolicyDecision:PolicyDownload];
2036 }
2037
2038 - (void)use
2039 {
2040     [self receivedPolicyDecision:PolicyUse];
2041 }
2042
2043 - (void)continue
2044 {
2045     [self receivedPolicyDecision:PolicyUse];
2046 }
2047
2048 @end