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