tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebKit / mac / WebCoreSupport / WebFrameLoaderClient.mm
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 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/MouseEvent.h>
108 #import <WebCore/Page.h>
109 #import <WebCore/PlatformString.h>
110 #import <WebCore/PluginViewBase.h>
111 #import <WebCore/ResourceError.h>
112 #import <WebCore/ResourceHandle.h>
113 #import <WebCore/ResourceLoader.h>
114 #import <WebCore/ResourceRequest.h>
115 #import <WebCore/ScriptController.h>
116 #import <WebCore/SharedBuffer.h>
117 #import <WebCore/WebCoreObjCExtras.h>
118 #import <WebCore/Widget.h>
119 #import <WebKit/DOMElement.h>
120 #import <WebKit/DOMHTMLFormElement.h>
121 #import <WebKitSystemInterface.h>
122 #import <runtime/InitializeThreading.h>
123 #import <wtf/MainThread.h>
124 #import <wtf/PassRefPtr.h>
125
126 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
127 #import <WebCore/HTMLMediaElement.h>
128 #endif
129
130 #if ENABLE(JAVA_BRIDGE)
131 #import "WebJavaPlugIn.h"
132 #endif
133
134 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
135 #import "NetscapePluginHostManager.h"
136 #import "WebHostedNetscapePluginView.h"
137 #endif
138
139 using namespace WebCore;
140 using namespace HTMLNames;
141 using namespace std;
142
143 #if ENABLE(JAVA_BRIDGE)
144 @interface NSView (WebJavaPluginDetails)
145 - (jobject)pollForAppletInWindow:(NSWindow *)window;
146 @end
147 #endif
148
149 // For backwards compatibility with older WebKit plug-ins.
150 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
151 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
152 NSString *WebPluginContainerKey = @"WebPluginContainer";
153
154 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> {
155     Frame* m_frame;
156 }
157 - (id)initWithWebCoreFrame:(Frame*)frame;
158 - (void)invalidate;
159 @end
160
161 static inline WebDataSource *dataSource(DocumentLoader* loader)
162 {
163     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
164 }
165
166 // Quirk for the Apple Dictionary application.
167 //
168 // If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,
169 // then for that frame's document, ignore changes to the scrolling attribute of frames. That script
170 // has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling
171 // attribute needs to be ignored to avoid showing extra scroll bars in the window.
172 // This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).
173
174 static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request)
175 {
176     if (!request.url().isLocalFile())
177         return;
178     if (!request.url().string().endsWith("MainPageJavaScript.js"))
179         return;
180     Frame* frame = core(client->webFrame());
181     if (!frame)
182         return;
183     if (frame->tree()->parent())
184         return;
185     Document* document = frame->document();
186     if (!document)
187         return;
188     HTMLHeadElement* head = document->head();
189     if (!head)
190         return;
191     for (Node* c = head->firstChild(); c; c = c->nextSibling()) {
192         if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") {
193             document->setFrameElementsShouldIgnoreScrolling(true);
194             return;
195         }
196     }
197 }
198
199 static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request)
200 {
201     // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in
202     // all applications other than Apple Dictionary.
203     static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"];
204     if (isAppleDictionary)
205         applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);
206 }
207
208 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
209     : m_webFrame(webFrame)
210     , m_policyFunction(0)
211 {
212 }
213
214 void WebFrameLoaderClient::frameLoaderDestroyed()
215 {
216     [m_webFrame.get() _clearCoreFrame];
217     delete this;
218 }
219
220 bool WebFrameLoaderClient::hasWebView() const
221 {
222     return [m_webFrame.get() webView] != nil;
223 }
224
225 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
226 {
227     [dataSource(loader) _makeRepresentation];
228 }
229
230 bool WebFrameLoaderClient::hasHTMLView() const
231 {
232     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
233     return [view isKindOfClass:[WebHTMLView class]];
234 }
235
236 void WebFrameLoaderClient::forceLayout()
237 {
238     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
239     [view setNeedsLayout:YES];
240     [view layout];
241 }
242
243 void WebFrameLoaderClient::forceLayoutForNonHTML()
244 {
245     WebFrameView *thisView = m_webFrame->_private->webFrameView;
246     NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
247     ASSERT(thisDocumentView != nil);
248     
249     // Tell the just loaded document to layout.  This may be necessary
250     // for non-html content that needs a layout message.
251     if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) {
252         [thisDocumentView setNeedsLayout:YES];
253         [thisDocumentView layout];
254         [thisDocumentView setNeedsDisplay:YES];
255     }
256 }
257
258 void WebFrameLoaderClient::setCopiesOnScroll()
259 {
260     [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
261 }
262
263 void WebFrameLoaderClient::detachedFromParent2()
264 {
265     //remove any NetScape plugins that are children of this frame because they are about to be detached
266     WebView *webView = getWebView(m_webFrame.get());
267     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
268     [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
269 }
270
271 void WebFrameLoaderClient::detachedFromParent3()
272 {
273     [m_webFrame->_private->webFrameView release];
274     m_webFrame->_private->webFrameView = nil;
275 }
276
277 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
278 {
279 #if USE(CFNETWORK)
280     ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
281     WebView *webView = getWebView(m_webFrame.get());
282     CFURLConnectionRef connection = handle->connection();
283     [WebDownload _downloadWithLoadingCFURLConnection:connection
284                                                                      request:request.cfURLRequest()
285                                                                     response:response.cfURLResponse()
286                                                                     delegate:[webView downloadDelegate]
287                                                                        proxy:nil];
288
289     // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
290     handle->releaseConnectionForDownload();
291     CFRelease(connection);
292 #else
293     id proxy = handle->releaseProxy();
294     ASSERT(proxy);
295     
296     WebView *webView = getWebView(m_webFrame.get());
297     [WebDownload _downloadWithLoadingConnection:handle->connection()
298                                                                 request:request.nsURLRequest()
299                                                                response:response.nsURLResponse()
300                                                                delegate:[webView downloadDelegate]
301                                                                   proxy:proxy];
302 #endif
303 }
304
305 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
306 {
307     applyAppleDictionaryApplicationQuirk(this, request);
308
309     WebView *webView = getWebView(m_webFrame.get());
310     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
311     if (!implementations->didLoadResourceFromMemoryCacheFunc)
312         return false;
313
314     CallResourceLoadDelegate(implementations->didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
315     return true;
316 }
317
318 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
319 {
320     WebView *webView = getWebView(m_webFrame.get());
321     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
322
323     id object = nil;
324     BOOL shouldRelease = NO;
325     if (implementations->identifierForRequestFunc)
326         object = CallResourceLoadDelegate(implementations->identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
327     else {
328         object = [[NSObject alloc] init];
329         shouldRelease = YES;
330     }
331
332     [webView _addObject:object forIdentifier:identifier];
333
334     if (shouldRelease)
335         [object release];
336 }
337
338 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
339 {
340     applyAppleDictionaryApplicationQuirk(this, request);
341
342     WebView *webView = getWebView(m_webFrame.get());
343     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
344
345     if (redirectResponse.isNull())
346         static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
347
348     if (implementations->willSendRequestFunc)
349         request = (NSURLRequest *)CallResourceLoadDelegate(implementations->willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
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::dispatchDidFirstLayout()
660 {
661     WebView *webView = getWebView(m_webFrame.get());
662     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
663     if (implementations->didFirstLayoutInFrameFunc)
664         CallFrameLoadDelegate(implementations->didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
665     
666     // See WebFrameLoaderClient::provisionalLoadStarted.
667     WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
668     if ([getWebView(m_webFrame.get()) drawsBackground])
669         [scrollView setDrawsBackground:YES];
670 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
671     [scrollView setVerticalScrollElasticity:NSScrollElasticityAutomatic];
672     [scrollView setHorizontalScrollElasticity:NSScrollElasticityAutomatic];
673 #endif
674 }
675
676 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
677 {
678     WebView *webView = getWebView(m_webFrame.get());
679     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
680     if (implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc)
681         CallFrameLoadDelegate(implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc, webView, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:), m_webFrame.get());
682 }
683
684 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
685 {
686     WebView *currentWebView = getWebView(m_webFrame.get());
687     NSDictionary *features = [[NSDictionary alloc] init];
688     WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView 
689                                                 createWebViewWithRequest:nil
690                                                           windowFeatures:features];
691     [features release];
692     
693 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
694     if (newWebView)
695         WebKit::NetscapePluginHostManager::shared().didCreateWindow();
696 #endif
697         
698     return core([newWebView mainFrame]);
699 }
700
701 void WebFrameLoaderClient::dispatchShow()
702 {
703     WebView *webView = getWebView(m_webFrame.get());
704     [[webView _UIDelegateForwarder] webViewShow:webView];
705 }
706
707 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function,
708     const ResourceResponse& response, const ResourceRequest& request)
709 {
710     WebView *webView = getWebView(m_webFrame.get());
711
712     [[webView _policyDelegateForwarder] webView:webView
713                         decidePolicyForMIMEType:response.mimeType()
714                                         request:request.nsURLRequest()
715                                           frame:m_webFrame.get()
716                                decisionListener:setUpPolicyListener(function).get()];
717 }
718
719 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
720     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
721 {
722     WebView *webView = getWebView(m_webFrame.get());
723     [[webView _policyDelegateForwarder] webView:webView
724             decidePolicyForNewWindowAction:actionDictionary(action, formState)
725                                    request:request.nsURLRequest()
726                               newFrameName:frameName
727                           decisionListener:setUpPolicyListener(function).get()];
728 }
729
730 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
731     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
732 {
733     WebView *webView = getWebView(m_webFrame.get());
734     [[webView _policyDelegateForwarder] webView:webView
735                 decidePolicyForNavigationAction:actionDictionary(action, formState)
736                                         request:request.nsURLRequest()
737                                           frame:m_webFrame.get()
738                                decisionListener:setUpPolicyListener(function).get()];
739 }
740
741 void WebFrameLoaderClient::cancelPolicyCheck()
742 {
743     [m_policyListener.get() invalidate];
744     m_policyListener = nil;
745     m_policyFunction = 0;
746 }
747
748 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
749 {
750     WebView *webView = getWebView(m_webFrame.get());
751     [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];    
752 }
753
754 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
755 {
756     id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
757     if (!formDelegate) {
758         (core(m_webFrame.get())->loader()->policyChecker()->*function)(PolicyUse);
759         return;
760     }
761
762     const StringPairVector& textFieldValues = formState->textFieldValues();
763     size_t size = textFieldValues.size();
764     NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:size];
765     for (size_t i = 0; i < size; ++i)
766         [dictionary setObject:textFieldValues[i].second forKey:textFieldValues[i].first];
767
768     CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceFrame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
769
770     [dictionary release];
771 }
772
773 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
774 {
775 }
776
777 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
778 {
779     [dataSource(loader) _revertToProvisionalState];
780 }
781
782 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
783 {
784     [dataSource(loader) _setMainDocumentError:error];
785 }
786
787 void WebFrameLoaderClient::willChangeEstimatedProgress()
788 {
789     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
790 }
791
792 void WebFrameLoaderClient::didChangeEstimatedProgress()
793 {
794     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
795 }
796
797 void WebFrameLoaderClient::postProgressStartedNotification()
798 {
799     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
800 }
801
802 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
803 {
804     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
805 }
806
807 void WebFrameLoaderClient::postProgressFinishedNotification()
808 {
809     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
810 }
811
812 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
813 {
814     [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
815 }
816
817 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
818 {
819     // FIXME: Should download full request.
820     [getWebView(m_webFrame.get()) _downloadURL:request.url()];
821 }
822
823 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
824 {
825     // FIXME: Should do this only in main frame case, right?
826     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
827 }
828
829 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
830 {
831     // FIXME: Should do this only in main frame case, right?
832     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
833 }
834
835 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
836 {
837     NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
838     [dataSource(loader) _receivedData:nsData];
839     [nsData release];
840 }
841
842 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
843 {
844     [dataSource(loader) _finishedLoading];
845 }
846
847 void WebFrameLoaderClient::updateGlobalHistory()
848 {
849     WebView* view = getWebView(m_webFrame.get());
850     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
851
852     if ([view historyDelegate]) {
853         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
854         if (implementations->navigatedFunc) {
855             WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->urlForHistory()
856                                                                              title:loader->title().string()
857                                                                    originalRequest:loader->originalRequestCopy().nsURLRequest()
858                                                                           response:loader->response().nsURLResponse()
859                                                                  hasSubstituteData:loader->substituteData().isValid()
860                                                               clientRedirectSource:loader->clientRedirectSourceForHistory()];
861
862             CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
863             [data release];
864         }
865     
866         return;
867     }
868
869     [[WebHistory optionalSharedHistory] _visitedURL:loader->urlForHistory() 
870                                           withTitle:loader->title().string()
871                                              method:loader->originalRequestCopy().httpMethod()
872                                          wasFailure:loader->urlForHistoryReflectsFailure()
873                                  increaseVisitCount:!loader->clientRedirectSourceForHistory()]; // Do not increase visit count due to navigations that were not initiated by the user directly, avoiding growth from programmatic reloads.
874 }
875
876 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
877 {
878     WebView* view = getWebView(m_webFrame.get());
879     WebHistoryDelegateImplementationCache* implementations = [view historyDelegate] ? WebViewGetHistoryDelegateImplementations(view) : 0;
880     
881     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
882     ASSERT(loader->unreachableURL().isEmpty());
883
884     if (!loader->clientRedirectSourceForHistory().isNull()) {
885         if (implementations) {
886             if (implementations->clientRedirectFunc) {
887                 CallHistoryDelegate(implementations->clientRedirectFunc, view, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:), 
888                     loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_webFrame.get());
889             }
890         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->clientRedirectSourceForHistory()])
891             core(item)->addRedirectURL(loader->clientRedirectDestinationForHistory());
892     }
893
894     if (!loader->serverRedirectSourceForHistory().isNull()) {
895         if (implementations) {
896             if (implementations->serverRedirectFunc) {
897                 CallHistoryDelegate(implementations->serverRedirectFunc, view, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:), 
898                     loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_webFrame.get());
899             }
900         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->serverRedirectSourceForHistory()])
901             core(item)->addRedirectURL(loader->serverRedirectDestinationForHistory());
902     }
903 }
904
905 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
906 {
907     WebView* view = getWebView(m_webFrame.get());
908     WebHistoryItem *webItem = kit(item);
909     
910     return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
911 }
912
913 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
914 {
915     return true;
916 }
917
918 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
919 {
920     HistoryItem* historyItem = 0;
921
922     if (Page* page = core(m_webFrame.get())->page()) {
923         if (!page->settings()->privateBrowsingEnabled())
924             historyItem = page->backForward()->currentItem();
925     }
926
927     WebView *webView = getWebView(m_webFrame.get());
928     [webView _setGlobalHistoryItem:historyItem];
929 }
930
931 void WebFrameLoaderClient::didDisplayInsecureContent()
932 {
933     WebView *webView = getWebView(m_webFrame.get());   
934     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
935     if (implementations->didDisplayInsecureContentFunc)
936         CallFrameLoadDelegate(implementations->didDisplayInsecureContentFunc, webView, @selector(webViewDidDisplayInsecureContent:));
937 }
938
939 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
940 {
941     WebView *webView = getWebView(m_webFrame.get());   
942     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
943     if (implementations->didRunInsecureContentFunc) {
944         RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin]);
945         CallFrameLoadDelegate(implementations->didRunInsecureContentFunc, webView, @selector(webView:didRunInsecureContent:), webSecurityOrigin.get());
946     }
947 }
948
949 void WebFrameLoaderClient::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
950 {
951     WebView *webView = getWebView(m_webFrame.get());   
952     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
953     if (implementations->didDetectXSSFunc) {
954         // FIXME: must pass didBlockEntirePage if we want to do more on mac than just pass tests.
955         NSURL* insecureNSURL = insecureURL;
956         CallFrameLoadDelegate(implementations->didDetectXSSFunc, webView, @selector(webView:didDetectXSS:), insecureNSURL);
957     }
958 }
959
960 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
961 {
962     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()];
963 }
964     
965 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
966 {
967     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()];
968 }
969
970 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
971 {
972     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()];
973 }
974
975 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
976 {
977     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
978 }
979
980 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
981 {
982     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
983 }
984
985 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
986 {
987     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()];    
988 }
989
990 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
991 {
992     NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
993                                                     contentURL:response.url()
994                                                  pluginPageURL:nil
995                                                     pluginName:nil
996                                                       MIMEType:response.mimeType()];
997     return [error autorelease];
998 }
999
1000 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1001 {
1002     // FIXME: Needs to check domain.
1003     // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
1004     // loading plugin content twice.  See <rdar://problem/4258008>
1005     return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
1006 }
1007
1008 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
1009 {
1010     Frame* frame = core(m_webFrame.get());
1011     Page* page = frame->page();
1012     BOOL forMainFrame = page && page->mainFrame() == frame;
1013     return [WebView _canHandleRequest:request.nsURLRequest() forMainFrame:forMainFrame];
1014 }
1015
1016 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1017 {
1018     return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType];
1019 }
1020
1021 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1022 {
1023     return [WebView canShowMIMETypeAsHTML:MIMEType];
1024 }
1025
1026 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1027 {
1028     return [WebView _representationExistsForURLScheme:URLScheme];
1029 }
1030
1031 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1032 {
1033     return [WebView _generatedMIMETypeForURLScheme:URLScheme];
1034 }
1035
1036 void WebFrameLoaderClient::frameLoadCompleted()
1037 {
1038     // Note: Can be called multiple times.
1039
1040     // See WebFrameLoaderClient::provisionalLoadStarted.
1041     if ([getWebView(m_webFrame.get()) drawsBackground])
1042         [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:YES];
1043 }
1044
1045 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* item)
1046 {
1047     if (!item)
1048         return;
1049     
1050     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1051
1052     // we might already be detached when this is called from detachFromParent, in which
1053     // case we don't want to override real data earlier gathered with (0,0)
1054     if ([docView superview] && [docView conformsToProtocol:@protocol(_WebDocumentViewState)])
1055         item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
1056 }
1057
1058 void WebFrameLoaderClient::restoreViewState()
1059 {
1060     HistoryItem* currentItem = core(m_webFrame.get())->loader()->history()->currentItem();
1061     ASSERT(currentItem);
1062
1063     // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
1064     // One counterexample is <rdar://problem/4917290>
1065     // For now, to cover this issue in release builds, there is no technical harm to returning
1066     // early and from a user standpoint - as in the above radar - the previous page load failed 
1067     // so there *is* no scroll state to restore!
1068     if (!currentItem)
1069         return;
1070     
1071     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1072     if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {        
1073         id state = currentItem->viewState();
1074         if (state) {
1075             [(id <_WebDocumentViewState>)docView setViewState:state];
1076         }
1077     }
1078 }
1079
1080 void WebFrameLoaderClient::provisionalLoadStarted()
1081 {    
1082     // Tell the scroll view not to draw a background so we can leave the contents of
1083     // the old page showing during the beginning of the loading process.
1084
1085     // This will stay set to NO until:
1086     //    1) The load gets far enough along: WebFrameLoader::frameLoadCompleted.
1087     //    2) The window is resized: -[WebFrameView setFrameSize:].
1088     // or 3) The view is moved out of the window: -[WebFrameView viewDidMoveToWindow].
1089     // Please keep the comments in these four functions in agreement with each other.
1090
1091     WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
1092     [scrollView setDrawsBackground:NO];
1093 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
1094     [scrollView setVerticalScrollElasticity:NSScrollElasticityNone];
1095     [scrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
1096 #endif
1097 }
1098
1099 void WebFrameLoaderClient::didFinishLoad()
1100 {
1101     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];    
1102 }
1103
1104 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1105 {
1106     if (![m_webFrame.get() _dataSource]) {
1107         ASSERT(!core(m_webFrame.get())->tree()->childCount());
1108         return;
1109     }
1110     
1111     // Make sure that any work that is triggered by resigning first reponder can get done.
1112     // The main example where this came up is the textDidEndEditing that is sent to the
1113     // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
1114     // remove the views as a side-effect of freeing the frame, at which point we can't
1115     // post the FormDelegate messages.
1116     //
1117     // Note that this can also take FirstResponder away from a child of our frameView that
1118     // is not in a child frame's view.  This is OK because we are in the process
1119     // of loading new content, which will blow away all editors in this top frame, and if
1120     // a non-editor is firstReponder it will not be affected by endEditingFor:.
1121     // Potentially one day someone could write a DocView whose editors were not all
1122     // replaced by loading new content, but that does not apply currently.
1123     NSView *frameView = m_webFrame->_private->webFrameView;
1124     NSWindow *window = [frameView window];
1125     NSResponder *firstResp = [window firstResponder];
1126     if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
1127         [window endEditingFor:firstResp];
1128 }
1129
1130 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1131 {
1132     RefPtr<WebDocumentLoaderMac> loader = WebDocumentLoaderMac::create(request, substituteData);
1133
1134     WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
1135     loader->setDataSource(dataSource, getWebView(m_webFrame.get()));
1136     [dataSource release];
1137
1138     return loader.release();
1139 }
1140
1141 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1142 {
1143     WebView* view = getWebView(m_webFrame.get());
1144     
1145     if ([view historyDelegate]) {
1146         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
1147         if (!implementations->setTitleFunc)
1148             return;
1149             
1150         // FIXME: use direction of title.
1151         CallHistoryDelegate(implementations->setTitleFunc, view, @selector(webView:updateHistoryTitle:forURL:), (NSString *)title.string(), (NSString *)url);
1152         return;
1153     }
1154     
1155     NSURL* nsURL = url;
1156     nsURL = [nsURL _webkit_canonicalize];
1157     if(!nsURL)
1158         return;
1159     NSString *titleNSString = title.string();
1160        
1161     [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
1162 }
1163
1164 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1165 {
1166     OwnPtr<WebCachedFramePlatformData> webPlatformData = adoptPtr(new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]));
1167     cachedFrame->setCachedFramePlatformData(webPlatformData.release());
1168 }
1169
1170 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
1171 {
1172     WebCachedFramePlatformData* platformData = reinterpret_cast<WebCachedFramePlatformData*>(cachedFrame->cachedFramePlatformData());
1173     NSView <WebDocumentView> *cachedView = platformData->webDocumentView();
1174     ASSERT(cachedView != nil);
1175     ASSERT(cachedFrame->documentLoader());
1176     [cachedView setDataSource:dataSource(cachedFrame->documentLoader())];
1177     
1178     // clean up webkit plugin instances before WebHTMLView gets freed.
1179     WebView *webView = getWebView(m_webFrame.get());
1180     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1181     
1182     [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
1183 }
1184
1185 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1186 {
1187     WebView *webView = getWebView(m_webFrame.get());
1188     WebDataSource *dataSource = [m_webFrame.get() _dataSource];
1189
1190     bool willProduceHTMLView = [m_webFrame->_private->webFrameView _viewClassForMIMEType:[dataSource _responseMIMEType]] == [WebHTMLView class];
1191     bool canSkipCreation = core(m_webFrame.get())->loader()->stateMachine()->committingFirstRealLoad() && willProduceHTMLView;
1192     if (canSkipCreation) {
1193         [[m_webFrame->_private->webFrameView documentView] setDataSource:dataSource];
1194         return;
1195     }
1196
1197     // Don't suppress scrollbars before the view creation if we're making the view for a non-HTML view.
1198     if (!willProduceHTMLView)
1199         [[m_webFrame->_private->webFrameView _scrollView] setScrollBarsSuppressed:NO repaintOnUnsuppress:NO];
1200     
1201     // clean up webkit plugin instances before WebHTMLView gets freed.
1202     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1203     
1204     NSView <WebDocumentView> *documentView = [m_webFrame->_private->webFrameView _makeDocumentViewForDataSource:dataSource];
1205     if (!documentView)
1206         return;
1207
1208     // FIXME: Could we skip some of this work for a top-level view that is not a WebHTMLView?
1209
1210     // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
1211     Frame* coreFrame = core(m_webFrame.get());
1212     Page* page = coreFrame->page();
1213     bool isMainFrame = coreFrame == page->mainFrame();
1214     if (isMainFrame && coreFrame->view())
1215         coreFrame->view()->setParentVisible(false);
1216     coreFrame->setView(0);
1217     RefPtr<FrameView> coreView = FrameView::create(coreFrame);
1218     coreFrame->setView(coreView);
1219
1220     [m_webFrame.get() _updateBackgroundAndUpdatesWhileOffscreen];
1221     [m_webFrame->_private->webFrameView _install];
1222
1223     if (isMainFrame)
1224         coreView->setParentVisible(true);
1225
1226     // Call setDataSource on the document view after it has been placed in the view hierarchy.
1227     // This what we for the top-level view, so should do this for views in subframes as well.
1228     [documentView setDataSource:dataSource];
1229
1230     // The following is a no-op for WebHTMLRepresentation, but for custom document types
1231     // like the ones that Safari uses for bookmarks it is the only way the DocumentLoader
1232     // will get the proper title.
1233     if (DocumentLoader* documentLoader = [dataSource _documentLoader])
1234         documentLoader->setTitle(StringWithDirection([dataSource pageTitle], LTR));
1235
1236     if (HTMLFrameOwnerElement* owner = coreFrame->ownerElement())
1237         coreFrame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
1238         
1239     // If the document view implicitly became first responder, make sure to set the focused frame properly.
1240     if ([[documentView window] firstResponder] == documentView) {
1241         page->focusController()->setFocusedFrame(coreFrame);
1242         page->focusController()->setFocused(true);
1243     }
1244 }
1245
1246 void WebFrameLoaderClient::didSaveToPageCache()
1247 {
1248 }
1249
1250 void WebFrameLoaderClient::didRestoreFromPageCache()
1251 {
1252 }
1253
1254 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1255 {
1256 }
1257
1258 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
1259 {
1260     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1261
1262     [m_policyListener.get() invalidate];
1263
1264     WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
1265     m_policyListener = listener;
1266     [listener release];
1267     m_policyFunction = function;
1268
1269     return listener;
1270 }
1271
1272 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1273 {
1274     ASSERT(m_policyListener);
1275     ASSERT(m_policyFunction);
1276
1277     FramePolicyFunction function = m_policyFunction;
1278
1279     m_policyListener = nil;
1280     m_policyFunction = 0;
1281
1282     (core(m_webFrame.get())->loader()->policyChecker()->*function)(action);
1283 }
1284
1285 String WebFrameLoaderClient::userAgent(const KURL& url)
1286 {
1287     WebView *webView = getWebView(m_webFrame.get());
1288     ASSERT(webView);
1289
1290     // We should never get here with nil for the WebView unless there is a bug somewhere else.
1291     // But if we do, it's better to return the empty string than just crashing on the spot.
1292     // Most other call sites are tolerant of nil because of Objective-C behavior, but this one
1293     // is not because the return value of _userAgentForURL is a const KURL&.
1294     if (!webView)
1295         return String("");
1296
1297     return [webView userAgentForURL:url];
1298 }
1299
1300 static const MouseEvent* findMouseEvent(const Event* event)
1301 {
1302     for (const Event* e = event; e; e = e->underlyingEvent())
1303         if (e->isMouseEvent())
1304             return static_cast<const MouseEvent*>(e);
1305     return 0;
1306 }
1307
1308 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action, PassRefPtr<FormState> formState) const
1309 {
1310     unsigned modifierFlags = 0;
1311     const Event* event = action.event();
1312     if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1313         if (keyStateEvent->ctrlKey())
1314             modifierFlags |= NSControlKeyMask;
1315         if (keyStateEvent->altKey())
1316             modifierFlags |= NSAlternateKeyMask;
1317         if (keyStateEvent->shiftKey())
1318             modifierFlags |= NSShiftKeyMask;
1319         if (keyStateEvent->metaKey())
1320             modifierFlags |= NSCommandKeyMask;
1321     }
1322
1323     NSURL *originalURL = action.url();
1324
1325     NSMutableDictionary *result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
1326         [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1327         [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1328         originalURL, WebActionOriginalURLKey,
1329         nil];
1330
1331     if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1332         WebElementDictionary *element = [[WebElementDictionary alloc]
1333             initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)];
1334         [result setObject:element forKey:WebActionElementKey];
1335         [element release];
1336
1337         [result setObject:[NSNumber numberWithInt:mouseEvent->button()] forKey:WebActionButtonKey];
1338     }
1339
1340     if (formState) {
1341         ASSERT(formState->form());
1342         [result setObject:kit(formState->form()) forKey:WebActionFormKey];
1343     }
1344
1345     return result;
1346 }
1347
1348 bool WebFrameLoaderClient::canCachePage() const
1349 {
1350     // We can only cache HTML pages right now
1351     return [[[m_webFrame.get() _dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1352 }
1353
1354 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1355     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1356 {
1357     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1358     
1359     ASSERT(m_webFrame);
1360     
1361     WebFrameView *childView = [[WebFrameView alloc] init];
1362     
1363     RefPtr<Frame> result = [WebFrame _createSubframeWithOwnerElement:ownerElement frameName:name frameView:childView];
1364     [childView release];
1365
1366     WebFrame *newFrame = kit(result.get());
1367
1368     if ([newFrame _dataSource])
1369         [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding());  
1370
1371     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1372     if (!result->page())
1373         return 0;
1374  
1375     core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, result.get());
1376
1377     // The frame's onload handler may have removed it from the document.
1378     if (!result->tree()->parent())
1379         return 0;
1380
1381     return result.release();
1382
1383     END_BLOCK_OBJC_EXCEPTIONS;
1384
1385     return 0;
1386 }
1387
1388 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page* oldPage)
1389 {
1390 }
1391
1392 void WebFrameLoaderClient::transferLoadingResourceFromPage(ResourceLoader* loader, const ResourceRequest& originalRequest, Page* oldPage)
1393 {
1394     ASSERT(oldPage != core(m_webFrame.get())->page());
1395
1396     unsigned long identifier = loader->identifier();
1397     ASSERT(![getWebView(m_webFrame.get()) _objectForIdentifier:identifier]);
1398
1399     assignIdentifierToInitialRequest(identifier, loader->documentLoader(), originalRequest);
1400
1401     [kit(oldPage) _removeObjectForIdentifier:identifier];
1402 }
1403
1404 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1405 {
1406     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1407
1408     String type = mimeType;
1409
1410     if (type.isEmpty()) {
1411         // Try to guess the MIME type based off the extension.
1412         NSURL *URL = url;
1413         NSString *extension = [[URL path] pathExtension];
1414         if ([extension length] > 0) {
1415             type = WKGetMIMETypeForExtension(extension);
1416             if (type.isEmpty()) {
1417                 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
1418                 if (WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForExtension:extension]) {
1419                     if ([package isKindOfClass:[WebPluginPackage class]]) 
1420                         return ObjectContentOtherPlugin;
1421 #if ENABLE(NETSCAPE_PLUGIN_API)
1422                     else {
1423                         ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
1424                         return ObjectContentNetscapePlugin;
1425                     }
1426 #endif
1427                 }
1428             }
1429         }
1430     }
1431
1432     if (type.isEmpty())
1433         return ObjectContentFrame; // Go ahead and hope that we can display the content.
1434
1435     WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForMIMEType:type];
1436     ObjectContentType plugInType = ObjectContentNone;
1437     if (package) {
1438 #if ENABLE(NETSCAPE_PLUGIN_API)
1439         if ([package isKindOfClass:[WebNetscapePluginPackage class]])
1440             plugInType = ObjectContentNetscapePlugin;
1441         else
1442 #endif
1443         {
1444             ASSERT([package isKindOfClass:[WebPluginPackage class]]);
1445             plugInType = ObjectContentOtherPlugin;
1446         }
1447     }
1448     
1449     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
1450         return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
1451
1452     if (plugInType != ObjectContentNone)
1453         return plugInType;
1454
1455     if ([m_webFrame->_private->webFrameView _viewClassForMIMEType:type])
1456         return ObjectContentFrame;
1457     
1458     return ObjectContentNone;
1459
1460     END_BLOCK_OBJC_EXCEPTIONS;
1461
1462     return ObjectContentNone;
1463 }
1464
1465 static NSMutableArray* kit(const Vector<String>& vector)
1466 {
1467     unsigned len = vector.size();
1468     NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1469     for (unsigned x = 0; x < len; x++)
1470         [array addObject:vector[x]];
1471     return array;
1472 }
1473
1474 static String parameterValue(const Vector<String>& paramNames, const Vector<String>& paramValues, const String& name)
1475 {
1476     size_t size = paramNames.size();
1477     ASSERT(size == paramValues.size());
1478     for (size_t i = 0; i < size; ++i) {
1479         if (equalIgnoringCase(paramNames[i], name))
1480             return paramValues[i];
1481     }
1482     return String();
1483 }
1484
1485 static NSView *pluginView(WebFrame *frame, WebPluginPackage *pluginPackage,
1486     NSArray *attributeNames, NSArray *attributeValues, NSURL *baseURL,
1487     DOMElement *element, BOOL loadManually)
1488 {
1489     WebHTMLView *docView = (WebHTMLView *)[[frame frameView] documentView];
1490     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1491         
1492     WebPluginController *pluginController = [docView _pluginController];
1493     
1494     // Store attributes in a dictionary so they can be passed to WebPlugins.
1495     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
1496     
1497     [pluginPackage load];
1498     Class viewFactory = [pluginPackage viewFactory];
1499     
1500     NSView *view = nil;
1501     NSDictionary *arguments = nil;
1502     
1503     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
1504         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1505             baseURL, WebPlugInBaseURLKey,
1506             attributes, WebPlugInAttributesKey,
1507             pluginController, WebPlugInContainerKey,
1508             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1509             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1510             element, WebPlugInContainingElementKey,
1511             nil];
1512         LOG(Plugins, "arguments:\n%@", arguments);
1513     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
1514         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1515             baseURL, WebPluginBaseURLKey,
1516             attributes, WebPluginAttributesKey,
1517             pluginController, WebPluginContainerKey,
1518             element, WebPlugInContainingElementKey,
1519             nil];
1520         LOG(Plugins, "arguments:\n%@", arguments);
1521     }
1522
1523     view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
1524     [attributes release];
1525     return view;
1526 }
1527
1528 class PluginWidget : public PluginViewBase {
1529 public:
1530     PluginWidget(NSView *view = 0)
1531         : PluginViewBase(view)
1532     {
1533     }
1534     
1535 private:
1536     virtual void invalidateRect(const IntRect& rect)
1537     {
1538         [platformWidget() setNeedsDisplayInRect:rect];
1539     }
1540 };
1541
1542 #if ENABLE(NETSCAPE_PLUGIN_API)
1543
1544 class NetscapePluginWidget : public PluginWidget {
1545 public:
1546     NetscapePluginWidget(WebBaseNetscapePluginView *view)
1547         : PluginWidget(view)
1548     {
1549     }
1550     
1551 #if USE(ACCELERATED_COMPOSITING)
1552     virtual PlatformLayer* platformLayer() const
1553     {
1554         return [(WebBaseNetscapePluginView *)platformWidget() pluginLayer];
1555     }
1556 #endif
1557
1558     virtual bool getFormValue(String& value)
1559     {
1560         NSString* nsValue = 0;
1561         if ([(WebBaseNetscapePluginView *)platformWidget() getFormValue:&nsValue]) {
1562             if (!nsValue)
1563                 return false;
1564             value = String(nsValue);
1565             [nsValue release];
1566             return true;
1567         }
1568         return false;
1569     }
1570
1571     virtual void handleEvent(Event* event)
1572     {
1573         Frame* frame = Frame::frameForWidget(this);
1574         if (!frame)
1575             return;
1576         
1577         NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
1578         if (event->type() == eventNames().mousemoveEvent)
1579             [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
1580         else if (event->type() == eventNames().mouseoverEvent)
1581             [(WebBaseNetscapePluginView *)platformWidget() handleMouseEntered:currentNSEvent];
1582         else if (event->type() == eventNames().mouseoutEvent)
1583             [(WebBaseNetscapePluginView *)platformWidget() handleMouseExited:currentNSEvent];
1584         else if (event->type() == eventNames().contextmenuEvent)
1585             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.
1586     }
1587
1588 private:
1589     virtual void notifyWidget(WidgetNotification notification)
1590     {
1591         switch (notification) {
1592         case WillPaintFlattened: {
1593             BEGIN_BLOCK_OBJC_EXCEPTIONS;
1594             [(WebBaseNetscapePluginView *)platformWidget() cacheSnapshot];
1595             END_BLOCK_OBJC_EXCEPTIONS;
1596             break;
1597         }
1598         case DidPaintFlattened: {
1599             BEGIN_BLOCK_OBJC_EXCEPTIONS;
1600             [(WebBaseNetscapePluginView *)platformWidget() clearCachedSnapshot];
1601             END_BLOCK_OBJC_EXCEPTIONS;
1602             break;
1603         }
1604         }
1605     }
1606 };
1607
1608 #if USE(PLUGIN_HOST_PROCESS)
1609 #define NETSCAPE_PLUGIN_VIEW WebHostedNetscapePluginView
1610 #else
1611 #define NETSCAPE_PLUGIN_VIEW WebNetscapePluginView
1612 #endif
1613
1614 #endif // ENABLE(NETSCAPE_PLUGIN_API)
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 ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1688             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, attributeKeys, kit(paramValues), baseURL, kit(element), loadManually);
1689             
1690 #if ENABLE(NETSCAPE_PLUGIN_API)
1691         else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1692             WebBaseNetscapePluginView *pluginView = [[[NETSCAPE_PLUGIN_VIEW alloc]
1693                 initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1694                 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1695                 URL:pluginURL
1696                 baseURL:baseURL
1697                 MIMEType:MIMEType
1698                 attributeKeys:attributeKeys
1699                 attributeValues:kit(paramValues)
1700                 loadManually:loadManually
1701                 element:element] autorelease];
1702             
1703             return adoptRef(new NetscapePluginWidget(pluginView));
1704         } 
1705 #endif
1706     } else
1707         errorCode = WebKitErrorCannotFindPlugIn;
1708
1709     if (!errorCode && !view)
1710         errorCode = WebKitErrorCannotLoadPlugIn;
1711     
1712     if (errorCode && m_webFrame) {
1713         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
1714         if (implementations->plugInFailedWithErrorFunc) {
1715             KURL pluginPageURL = document->completeURL(stripLeadingAndTrailingHTMLSpaces(parameterValue(paramNames, paramValues, "pluginspage")));
1716             if (!pluginPageURL.protocolInHTTPFamily())
1717                 pluginPageURL = KURL();
1718             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1719
1720             NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1721                                                             contentURL:pluginURL pluginPageURL:pluginPageURL pluginName:pluginName MIMEType:MIMEType];
1722             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1723                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1724             [error release];
1725         }
1726
1727         return 0;
1728     }
1729     
1730     ASSERT(view);
1731     return adoptRef(new PluginWidget(view));
1732
1733     END_BLOCK_OBJC_EXCEPTIONS;
1734
1735     return 0;
1736 }
1737
1738 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1739 {
1740     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1741
1742     WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[m_webFrame.get() _dataSource] representation];
1743
1744     NSView *pluginView = pluginWidget->platformWidget();
1745
1746 #if ENABLE(NETSCAPE_PLUGIN_API)
1747     if ([pluginView isKindOfClass:[NETSCAPE_PLUGIN_VIEW class]])
1748         [representation _redirectDataToManualLoader:(NETSCAPE_PLUGIN_VIEW *)pluginView forPluginView:pluginView];
1749     else {
1750 #else
1751     {
1752 #endif
1753         WebHTMLView *documentView = (WebHTMLView *)[[m_webFrame.get() frameView] documentView];
1754         ASSERT([documentView isKindOfClass:[WebHTMLView class]]);
1755         [representation _redirectDataToManualLoader:[documentView _pluginController] forPluginView:pluginView];
1756     }
1757
1758     END_BLOCK_OBJC_EXCEPTIONS;
1759 }
1760     
1761 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const KURL& baseURL, 
1762     const Vector<String>& paramNames, const Vector<String>& paramValues)
1763 {
1764 #if ENABLE(JAVA_BRIDGE)
1765     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1766
1767     NSView *view = nil;
1768
1769     NSString *MIMEType = @"application/x-java-applet";
1770     
1771     WebView *webView = getWebView(m_webFrame.get());
1772
1773     WebBasePluginPackage *pluginPackage = [webView _pluginForMIMEType:MIMEType];
1774
1775     if (pluginPackage) {
1776         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
1777             // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
1778             NSMutableArray *names = kit(paramNames);
1779             NSMutableArray *values = kit(paramValues);
1780             if (parameterValue(paramNames, paramValues, "width").isNull()) {
1781                 [names addObject:@"width"];
1782                 [values addObject:[NSString stringWithFormat:@"%d", size.width()]];
1783             }
1784             if (parameterValue(paramNames, paramValues, "height").isNull()) {
1785                 [names addObject:@"height"];
1786                 [values addObject:[NSString stringWithFormat:@"%d", size.height()]];
1787             }
1788             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, names, values, baseURL, kit(element), NO);
1789             if (view)
1790                 return adoptRef(new PluginWidget(view));
1791         } 
1792 #if ENABLE(NETSCAPE_PLUGIN_API)
1793         else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1794             view = [[[NETSCAPE_PLUGIN_VIEW alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1795                 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1796                 URL:nil
1797                 baseURL:baseURL
1798                 MIMEType:MIMEType
1799                 attributeKeys:kit(paramNames)
1800                 attributeValues:kit(paramValues)
1801                 loadManually:NO
1802                 element:element] autorelease];
1803             if (view)
1804                 return adoptRef(new NetscapePluginWidget(static_cast<WebBaseNetscapePluginView *>(view)));
1805         } else {
1806             ASSERT_NOT_REACHED();
1807         }
1808 #endif
1809     }
1810
1811     if (!view) {
1812         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(getWebView(m_webFrame.get()));
1813         if (implementations->plugInFailedWithErrorFunc) {
1814             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1815             NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable contentURL:nil pluginPageURL:nil pluginName:pluginName MIMEType:MIMEType];
1816             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1817                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1818             [error release];
1819         }
1820     }
1821
1822     END_BLOCK_OBJC_EXCEPTIONS;
1823 #endif // ENABLE(JAVA_BRIDGE)
1824     return 0;
1825 }
1826
1827 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1828 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize& size, HTMLMediaElement* element, const KURL& url,
1829     const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType)
1830 {
1831     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1832
1833     ASSERT(paramNames.size() == paramValues.size());
1834     ASSERT(mimeType);
1835
1836     int errorCode = 0;
1837     WebView *webView = getWebView(m_webFrame.get());
1838     NSURL *URL = url;
1839
1840     SEL selector = @selector(webView:plugInViewWithArguments:);
1841
1842     if ([[webView UIDelegate] respondsToSelector:selector]) {
1843         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:kit(paramNames)];
1844         NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1845             attributes, WebPlugInAttributesKey,
1846             [NSNumber numberWithInt:WebPlugInModeEmbed], WebPlugInModeKey,
1847             [NSNumber numberWithBool:YES], WebPlugInShouldLoadMainResourceKey,
1848             kit(element), WebPlugInContainingElementKey,
1849             URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
1850             nil];
1851
1852         NSView *view = CallUIDelegate(webView, selector, arguments);
1853
1854         [attributes release];
1855         [arguments release];
1856
1857         if (view)
1858             return adoptRef(new PluginWidget(view));
1859     }
1860
1861     WebBasePluginPackage *pluginPackage = [webView _videoProxyPluginForMIMEType:mimeType];
1862     Document* document = core(m_webFrame.get())->document();
1863     NSURL *baseURL = document->baseURL();
1864     NSView *view = nil;
1865
1866     if (pluginPackage) {
1867         if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1868             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, kit(paramNames), kit(paramValues), baseURL, kit(element), false);
1869     } else
1870         errorCode = WebKitErrorCannotFindPlugIn;
1871
1872     if (!errorCode && !view)
1873         errorCode = WebKitErrorCannotLoadPlugIn;
1874
1875     if (errorCode) {
1876         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1877             contentURL:URL pluginPageURL:nil pluginName:[pluginPackage pluginInfo].name MIMEType:mimeType];
1878         WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1879             error:error DOMElement:kit(element)] autorelease];
1880         view = nullView;
1881         [error release];
1882     }
1883     
1884     ASSERT(view);
1885     return adoptRef(new PluginWidget(view));
1886
1887     END_BLOCK_OBJC_EXCEPTIONS;
1888
1889     return 0;
1890 }
1891
1892 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget)
1893 {
1894     [WebPluginController pluginViewHidden:widget->platformWidget()];
1895 }
1896
1897 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget)
1898 {
1899     [WebPluginController addPlugInView:widget->platformWidget()];
1900 }
1901
1902 #endif  // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1903
1904 String WebFrameLoaderClient::overrideMediaType() const
1905 {
1906     NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle];
1907     if (overrideType)
1908         return overrideType;
1909     return String();
1910 }
1911
1912 void WebFrameLoaderClient::documentElementAvailable() {
1913 }
1914
1915 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1916 {
1917     WebView *webView = getWebView(m_webFrame.get());
1918     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1919
1920     if (implementations->didClearWindowObjectForFrameInScriptWorldFunc) {
1921         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameInScriptWorldFunc,
1922             webView, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:), m_webFrame.get(), [WebScriptWorld findOrCreateWorld:world]);
1923         return;
1924     }
1925
1926     if (world != mainThreadNormalWorld())
1927         return;
1928
1929     Frame *frame = core(m_webFrame.get());
1930     ScriptController *script = frame->script();
1931
1932     if (implementations->didClearWindowObjectForFrameFunc) {
1933         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:),
1934             script->windowScriptObject(), m_webFrame.get());
1935     } else if (implementations->windowScriptObjectAvailableFunc) {
1936         CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:),
1937             script->windowScriptObject());
1938     }
1939
1940     if ([webView scriptDebugDelegate]) {
1941         [m_webFrame.get() _detachScriptDebugger];
1942         [m_webFrame.get() _attachScriptDebugger];
1943     }
1944 }
1945
1946 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1947 {
1948 #if ENABLE(ICONDATABASE)
1949     [[m_webFrame.get() webView] _registerForIconNotification:listen];
1950 #endif
1951 }
1952
1953 void WebFrameLoaderClient::didPerformFirstNavigation() const
1954 {
1955     WebPreferences *preferences = [[m_webFrame.get() webView] preferences];
1956     if ([preferences automaticallyDetectsCacheModel] && [preferences cacheModel] < WebCacheModelDocumentBrowser)
1957         [preferences setCacheModel:WebCacheModelDocumentBrowser];
1958 }
1959
1960 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1961 {
1962     return WebFrameNetworkingContext::create(core(m_webFrame.get()));
1963 }
1964
1965 #if ENABLE(JAVA_BRIDGE)
1966 jobject WebFrameLoaderClient::javaApplet(NSView* view)
1967 {
1968     if ([view respondsToSelector:@selector(webPlugInGetApplet)])
1969         return [view webPlugInGetApplet];
1970
1971     // Compatibility with older versions of Java.
1972     // FIXME: Do we still need this?
1973     if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
1974         return [view pollForAppletInWindow:[[m_webFrame.get() frameView] window]];
1975
1976     return 0;
1977 }
1978 #endif
1979
1980 @implementation WebFramePolicyListener
1981 + (void)initialize
1982 {
1983     JSC::initializeThreading();
1984     WTF::initializeMainThreadToProcessMainThread();
1985     WebCoreObjCFinalizeOnMainThread(self);
1986 }
1987
1988 - (id)initWithWebCoreFrame:(Frame*)frame
1989 {
1990     self = [self init];
1991     if (!self)
1992         return nil;
1993     frame->ref();
1994     m_frame = frame;
1995     return self;
1996 }
1997
1998 - (void)invalidate
1999 {
2000     if (m_frame) {
2001         m_frame->deref();
2002         m_frame = 0;
2003     }
2004 }
2005
2006 - (void)dealloc
2007 {
2008     if (WebCoreObjCScheduleDeallocateOnMainThread([WebFramePolicyListener class], self))
2009         return;
2010
2011     if (m_frame)
2012         m_frame->deref();
2013     [super dealloc];
2014 }
2015
2016 - (void)finalize
2017 {
2018     ASSERT_MAIN_THREAD();
2019     if (m_frame)
2020         m_frame->deref();
2021     [super finalize];
2022 }
2023
2024 - (void)receivedPolicyDecision:(PolicyAction)action
2025 {
2026     RefPtr<Frame> frame = adoptRef(m_frame);
2027     m_frame = 0;
2028     if (frame)
2029         static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
2030 }
2031
2032 - (void)ignore
2033 {
2034     [self receivedPolicyDecision:PolicyIgnore];
2035 }
2036
2037 - (void)download
2038 {
2039     [self receivedPolicyDecision:PolicyDownload];
2040 }
2041
2042 - (void)use
2043 {
2044     [self receivedPolicyDecision:PolicyUse];
2045 }
2046
2047 - (void)continue
2048 {
2049     [self receivedPolicyDecision:PolicyUse];
2050 }
2051
2052 @end