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