Reviewed by Maciej
[WebKit-https.git] / WebKit / WebCoreSupport / WebFrameLoaderClient.mm
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "WebFrameLoaderClient.h"
30
31 // Terrible hack; lets us get at the WebFrame private structure.
32 #define private public
33 #import "WebFrame.h"
34 #undef private
35
36 #import "DOMElementInternal.h"
37 #import "WebBackForwardList.h"
38 #import "WebChromeClient.h"
39 #import "WebDataSourceInternal.h"
40 #import "WebPolicyDelegatePrivate.h"
41 #import "WebDefaultResourceLoadDelegate.h"
42 #import "WebDocumentInternal.h"
43 #import "WebDocumentLoaderMac.h"
44 #import "WebDownloadInternal.h"
45 #import "WebElementDictionary.h"
46 #import "WebFormDelegate.h"
47 #import "WebFrameBridge.h"
48 #import "WebFrameInternal.h"
49 #import "WebFrameLoadDelegate.h"
50 #import "WebFrameViewInternal.h"
51 #import "WebHTMLRepresentation.h"
52 #import "WebHTMLView.h"
53 #import "WebHistoryItemInternal.h"
54 #import "WebHistoryItemPrivate.h"
55 #import "WebHistoryPrivate.h"
56 #import "WebIconDatabaseInternal.h"
57 #import "WebKitErrorsPrivate.h"
58 #import "WebKitNSStringExtras.h"
59 #import "WebNSURLExtras.h"
60 #import "WebPanelAuthenticationHandler.h"
61 #import "WebPolicyDelegate.h"
62 #import "WebPreferences.h"
63 #import "WebResourceLoadDelegate.h"
64 #import "WebResourcePrivate.h"
65 #import "WebScriptDebugServerPrivate.h"
66 #import "WebUIDelegate.h"
67 #import "WebViewInternal.h"
68 #import <WebCore/AuthenticationMac.h>
69 #import <WebCore/BlockExceptions.h>
70 #import <WebCore/Chrome.h>
71 #import <WebCore/Document.h>
72 #import <WebCore/DocumentLoader.h>
73 #import <WebCore/EventHandler.h>
74 #import <WebCore/FormState.h>
75 #import <WebCore/FrameLoader.h>
76 #import <WebCore/FrameLoaderTypes.h>
77 #import <WebCore/FrameMac.h>
78 #import <WebCore/FrameTree.h>
79 #import <WebCore/HistoryItem.h>
80 #import <WebCore/HitTestResult.h>
81 #import <WebCore/HTMLFormElement.h>
82 #import <WebCore/IconDatabase.h>
83 #import <WebCore/LoaderNSURLExtras.h>
84 #import <WebCore/MouseEvent.h>
85 #import <WebCore/Page.h>
86 #import <WebCore/PageCache.h>
87 #import <WebCore/PageState.h>
88 #import <WebCore/PlatformString.h>
89 #import <WebCore/ResourceError.h>
90 #import <WebCore/ResourceHandle.h>
91 #import <WebCore/ResourceLoader.h>
92 #import <WebCore/ResourceRequest.h>
93 #import <WebCore/WebCoreFrameBridge.h>
94 #import <WebCore/WebDataProtocol.h>
95 #import <WebCore/Widget.h>
96 #import <WebKit/DOMElement.h>
97 #import <WebKit/DOMHTMLFormElement.h>
98 #import <WebKitSystemInterface.h>
99 #import <wtf/PassRefPtr.h>
100
101 using namespace WebCore;
102
103 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener>
104 {
105     Frame* m_frame;
106 }
107 - (id)initWithWebCoreFrame:(Frame*)frame;
108 - (void)invalidate;
109 @end
110
111 static inline WebView *getWebView(DocumentLoader* loader)
112 {
113     return kit(loader->frameLoader()->frame()->page());
114 }
115
116 static inline WebDataSource *dataSource(DocumentLoader* loader)
117 {
118     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
119 }
120
121 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
122     : m_webFrame(webFrame)
123     , m_policyFunction(0)
124     , m_archivedResourcesDeliveryTimer(this, &WebFrameLoaderClient::deliverArchivedResources)
125 {
126 }
127
128 void WebFrameLoaderClient::frameLoaderDestroyed()
129 {
130     delete this;
131 }
132
133 bool WebFrameLoaderClient::hasWebView() const
134 {
135     return [m_webFrame.get() webView] != nil;
136 }
137
138 bool WebFrameLoaderClient::hasFrameView() const
139 {
140     return m_webFrame->_private->webFrameView != nil;
141 }
142
143 bool WebFrameLoaderClient::privateBrowsingEnabled() const
144 {
145     return [[getWebView(m_webFrame.get()) preferences] privateBrowsingEnabled];
146 }
147
148 void WebFrameLoaderClient::makeDocumentView()
149 {
150     WebFrameView *v = m_webFrame->_private->webFrameView;
151     WebDataSource *ds = [m_webFrame.get() dataSource];
152
153     NSView <WebDocumentView> *documentView = [v _makeDocumentViewForDataSource:ds];
154     if (!documentView)
155         return;
156
157     WebFrameBridge *bridge = m_webFrame->_private->bridge;
158
159     // FIXME: We could save work and not do this for a top-level view that is not a WebHTMLView.
160     [bridge createFrameViewWithNSView:documentView marginWidth:[v _marginWidth] marginHeight:[v _marginHeight]];
161     [m_webFrame.get() _updateBackground];
162     [bridge installInFrame:[v _scrollView]];
163
164     // Call setDataSource on the document view after it has been placed in the view hierarchy.
165     // This what we for the top-level view, so should do this for views in subframes as well.
166     [documentView setDataSource:ds];
167 }
168
169 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
170 {
171     [dataSource(loader) _makeRepresentation];
172 }
173
174 void WebFrameLoaderClient::setDocumentViewFromPageCache(PageCache* pageCache)
175 {
176     DocumentLoader* cachedDocumentLoader = pageCache->documentLoader();
177     ASSERT(cachedDocumentLoader);
178     NSView <WebDocumentView> *cachedView = pageCache->documentView();
179     ASSERT(cachedView != nil);
180     [cachedView setDataSource:dataSource(cachedDocumentLoader)];
181     [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
182 }
183
184 void WebFrameLoaderClient::forceLayout()
185 {
186     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
187     if ([view isKindOfClass:[WebHTMLView class]])
188         [(WebHTMLView *)view setNeedsToApplyStyles:YES];
189     [view setNeedsLayout:YES];
190     [view layout];
191 }
192
193 void WebFrameLoaderClient::forceLayoutForNonHTML()
194 {
195     WebFrameView *thisView = m_webFrame->_private->webFrameView;
196     NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
197     ASSERT(thisDocumentView != nil);
198     
199     // Tell the just loaded document to layout.  This may be necessary
200     // for non-html content that needs a layout message.
201     if (!([[m_webFrame.get() dataSource] _isDocumentHTML])) {
202         [thisDocumentView setNeedsLayout:YES];
203         [thisDocumentView layout];
204         [thisDocumentView setNeedsDisplay:YES];
205     }
206 }
207
208 void WebFrameLoaderClient::setCopiesOnScroll()
209 {
210     [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
211 }
212
213 void WebFrameLoaderClient::detachedFromParent2()
214 {
215     [m_webFrame->_private->inspectors makeObjectsPerformSelector:@selector(_webFrameDetached:) withObject:m_webFrame.get()];
216     [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
217 }
218
219 void WebFrameLoaderClient::detachedFromParent3()
220 {
221     [m_webFrame->_private->webFrameView release];
222     m_webFrame->_private->webFrameView = nil;
223 }
224
225 void WebFrameLoaderClient::detachedFromParent4()
226 {
227     m_webFrame->_private->bridge = nil;
228 }
229
230 void WebFrameLoaderClient::loadedFromPageCache()
231 {
232     // Release the resources kept in the page cache.
233     // They will be reset when we leave this page.
234     // The WebCore side of the page cache will have already been invalidated by
235     // the bridge to prevent premature release.
236     core(m_webFrame.get())->loader()->currentHistoryItem()->setHasPageCache(false);
237 }
238
239 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
240 {
241     id proxy = handle->releaseProxy();
242     ASSERT(proxy);
243     [WebDownload _downloadWithLoadingConnection:handle->connection()
244                                         request:request.nsURLRequest()
245                                        response:response.nsURLResponse()
246                                        delegate:[getWebView(m_webFrame.get()) downloadDelegate]
247                                           proxy:proxy];
248 }
249
250 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
251 {
252     WebView *webView = getWebView(loader);
253     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
254     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
255
256     if (!implementations.delegateImplementsDidLoadResourceFromMemoryCache)
257         return false;
258
259     implementations.didLoadResourceFromMemoryCacheFunc(resourceLoadDelegate, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), webView, request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
260     return true;
261 }
262
263 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
264 {
265     WebView *webView = getWebView(loader);
266     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
267     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
268
269     id object;
270     BOOL shouldRelease = NO;
271     if (implementations.delegateImplementsIdentifierForRequest)
272         object = implementations.identifierForRequestFunc(resourceLoadDelegate, @selector(webView:identifierForInitialRequest:fromDataSource:), webView, request.nsURLRequest(), dataSource(loader));
273     else {
274         object = [[NSObject alloc] init];
275         shouldRelease = YES;
276     }
277     [webView _addObject:object forIdentifier:identifier];
278     if (shouldRelease)
279         [object release];
280 }
281
282 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
283 {
284     WebView *webView = getWebView(loader);
285     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
286     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
287
288     if (implementations.delegateImplementsWillSendRequest)
289         request = implementations.willSendRequestFunc(resourceLoadDelegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), webView, [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
290 }
291
292 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
293 {
294     WebView *webView = getWebView(m_webFrame.get());
295     id resourceLoadDelegate = [webView resourceLoadDelegate];
296     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
297
298     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
299
300     if (implementations.delegateImplementsDidReceiveAuthenticationChallenge) {
301         [resourceLoadDelegate webView:webView resource:[webView _objectForIdentifier:identifier] didReceiveAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
302         return;
303     }
304
305     NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
306     [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
307 }
308
309 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
310 {
311     WebView *webView = getWebView(m_webFrame.get());
312     id resourceLoadDelegate = [webView resourceLoadDelegate];
313     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
314
315     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
316
317     if (implementations.delegateImplementsDidCancelAuthenticationChallenge) {
318         [resourceLoadDelegate webView:webView resource:[webView _objectForIdentifier:identifier] didCancelAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
319         return;
320     }
321
322     [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
323 }
324
325 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
326 {
327     WebView *webView = getWebView(loader);
328     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
329     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
330
331     if (implementations.delegateImplementsDidReceiveResponse)
332         implementations.didReceiveResponseFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveResponse:fromDataSource:), webView, [webView _objectForIdentifier:identifier], response.nsURLResponse(), dataSource(loader));
333 }
334
335 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int lengthReceived)
336 {
337     WebView *webView = getWebView(loader);
338     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
339     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
340
341     if (implementations.delegateImplementsDidReceiveContentLength)
342         implementations.didReceiveContentLengthFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveContentLength:fromDataSource:), webView, [webView _objectForIdentifier:identifier], (WebNSUInteger)lengthReceived, dataSource(loader));
343 }
344
345 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
346 {
347     WebView *webView = getWebView(loader);
348     id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
349     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
350     
351     if (implementations.delegateImplementsDidFinishLoadingFromDataSource)
352         implementations.didFinishLoadingFromDataSourceFunc(resourceLoadDelegate, @selector(webView:resource:didFinishLoadingFromDataSource:), webView, [webView _objectForIdentifier:identifier], dataSource(loader));
353     [webView _removeObjectForIdentifier:identifier];
354 }
355
356 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
357 {
358     WebView *webView = getWebView(m_webFrame.get());
359     [[webView _resourceLoadDelegateForwarder] webView:webView resource:[webView _objectForIdentifier:identifier] didFailLoadingWithError:error fromDataSource:dataSource(loader)];
360     [webView _removeObjectForIdentifier:identifier];
361 }
362
363 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
364 {
365     WebView *webView = getWebView(m_webFrame.get());
366     [[webView _frameLoadDelegateForwarder] webView:webView didHandleOnloadEventsForFrame:m_webFrame.get()];
367 }
368
369 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
370 {
371     WebView *webView = getWebView(m_webFrame.get());
372     [[webView _frameLoadDelegateForwarder] webView:webView
373        didReceiveServerRedirectForProvisionalLoadForFrame:m_webFrame.get()];
374 }
375
376 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
377 {
378     WebView *webView = getWebView(m_webFrame.get());
379     [[webView _frameLoadDelegateForwarder] webView:webView didCancelClientRedirectForFrame:m_webFrame.get()];
380 }
381
382 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& URL, double delay, double fireDate)
383 {
384     WebView *webView = getWebView(m_webFrame.get());
385     [[webView _frameLoadDelegateForwarder] webView:webView
386                          willPerformClientRedirectToURL:URL.getNSURL()
387                                                   delay:delay
388                                                fireDate:[NSDate dateWithTimeIntervalSince1970:fireDate]
389                                                forFrame:m_webFrame.get()];
390 }
391
392 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
393 {
394     WebView *webView = getWebView(m_webFrame.get());   
395     [[webView _frameLoadDelegateForwarder] webView:webView didChangeLocationWithinPageForFrame:m_webFrame.get()];
396 }
397
398 void WebFrameLoaderClient::dispatchWillClose()
399 {
400     WebView *webView = getWebView(m_webFrame.get());   
401     [[webView _frameLoadDelegateForwarder] webView:webView willCloseFrame:m_webFrame.get()];
402 }
403
404 void WebFrameLoaderClient::dispatchDidReceiveIcon()
405 {
406     WebView *webView = getWebView(m_webFrame.get());   
407     ASSERT([m_webFrame.get() _isMainFrame]);
408     // FIXME: This willChangeValueForKey call is too late, because the icon has already changed by now.
409     [webView _willChangeValueForKey:_WebMainFrameIconKey];
410     id delegate = [webView frameLoadDelegate];
411     if ([delegate respondsToSelector:@selector(webView:didReceiveIcon:forFrame:)]) {
412         Image* image = IconDatabase::sharedIconDatabase()->
413             iconForPageURL(core(m_webFrame.get())->loader()->url().url(), IntSize(16, 16));
414         NSImage *icon = webGetNSImage(image, NSMakeSize(16, 16));
415         if (icon)
416             [delegate webView:webView didReceiveIcon:icon forFrame:m_webFrame.get()];
417     }
418     [webView _didChangeValueForKey:_WebMainFrameIconKey];
419 }
420
421 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
422 {
423     WebView *webView = getWebView(m_webFrame.get());   
424     [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
425     [[webView _frameLoadDelegateForwarder] webView:webView didStartProvisionalLoadForFrame:m_webFrame.get()];    
426 }
427
428 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
429 {
430     WebView *webView = getWebView(m_webFrame.get());   
431     [[webView _frameLoadDelegateForwarder] webView:webView didReceiveTitle:title forFrame:m_webFrame.get()];
432 }
433
434 void WebFrameLoaderClient::dispatchDidCommitLoad()
435 {
436     // Tell the client we've committed this URL.
437     ASSERT([m_webFrame->_private->webFrameView documentView] != nil);
438     
439     WebView *webView = getWebView(m_webFrame.get());   
440     [webView _didCommitLoadForFrame:m_webFrame.get()];
441     [[webView _frameLoadDelegateForwarder] webView:webView didCommitLoadForFrame:m_webFrame.get()];
442 }
443
444 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
445 {
446     WebView *webView = getWebView(m_webFrame.get());   
447     [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
448     [[webView _frameLoadDelegateForwarder] webView:webView didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
449     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
450 }
451
452 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
453 {
454     WebView *webView = getWebView(m_webFrame.get());   
455     [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
456     [[webView _frameLoadDelegateForwarder] webView:webView didFailLoadWithError:error forFrame:m_webFrame.get()];
457     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
458 }
459
460 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
461 {
462     WebView *webView = getWebView(m_webFrame.get());
463     id delegate = [webView frameLoadDelegate];
464     if ([delegate respondsToSelector:@selector(webView:didFinishDocumentLoadForFrame:)])
465         [delegate webView:webView didFinishDocumentLoadForFrame:m_webFrame.get()];
466 }
467
468 void WebFrameLoaderClient::dispatchDidFinishLoad()
469 {
470     WebView *webView = getWebView(m_webFrame.get());   
471     [webView _didFinishLoadForFrame:m_webFrame.get()];
472     [[webView _frameLoadDelegateForwarder] webView:webView didFinishLoadForFrame:m_webFrame.get()];
473     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
474 }
475
476 void WebFrameLoaderClient::dispatchDidFirstLayout()
477 {
478     WebView *webView = getWebView(m_webFrame.get());
479     [[webView _frameLoadDelegateForwarder] webView:webView didFirstLayoutInFrame:m_webFrame.get()];
480 }
481
482 Frame* WebFrameLoaderClient::dispatchCreatePage()
483 {
484     WebView *currentWebView = getWebView(m_webFrame.get());
485     id wd = [currentWebView UIDelegate];
486     if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
487         return core([[wd webView:currentWebView createWebViewWithRequest:nil] mainFrame]);
488     return 0;
489 }
490
491 void WebFrameLoaderClient::dispatchShow()
492 {
493     WebView *webView = getWebView(m_webFrame.get());
494     [[webView _UIDelegateForwarder] webViewShow:webView];
495 }
496
497 void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction function,
498     const String& MIMEType, const ResourceRequest& request)
499 {
500     WebView *webView = getWebView(m_webFrame.get());
501
502     [[webView _policyDelegateForwarder] webView:webView
503                         decidePolicyForMIMEType:MIMEType
504                                         request:request.nsURLRequest()
505                                           frame:m_webFrame.get()
506                                decisionListener:setUpPolicyListener(function).get()];
507 }
508
509 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
510     const NavigationAction& action, const ResourceRequest& request, const String& frameName)
511 {
512     WebView *webView = getWebView(m_webFrame.get());
513     [[webView _policyDelegateForwarder] webView:webView
514             decidePolicyForNewWindowAction:actionDictionary(action)
515                                    request:request.nsURLRequest()
516                               newFrameName:frameName
517                           decisionListener:setUpPolicyListener(function).get()];
518 }
519
520 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
521     const NavigationAction& action, const ResourceRequest& request)
522 {
523     WebView *webView = getWebView(m_webFrame.get());
524     [[webView _policyDelegateForwarder] webView:webView
525                 decidePolicyForNavigationAction:actionDictionary(action)
526                                         request:request.nsURLRequest()
527                                           frame:m_webFrame.get()
528                                decisionListener:setUpPolicyListener(function).get()];
529 }
530
531 void WebFrameLoaderClient::cancelPolicyCheck()
532 {
533     [m_policyListener.get() invalidate];
534     m_policyListener = nil;
535     m_policyFunction = 0;
536 }
537
538 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
539 {
540     WebView *webView = getWebView(m_webFrame.get());
541     [[webView _policyDelegateForwarder] webView:webView
542         unableToImplementPolicyWithError:error frame:m_webFrame.get()];    
543 }
544
545 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
546 {
547     id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
548     if (!formDelegate) {
549         (core(m_webFrame.get())->loader()->*function)(PolicyUse);
550         return;
551     }
552
553     NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:formState->values().size()];
554     HashMap<String, String>::const_iterator end = formState->values().end();
555     for (HashMap<String, String>::const_iterator it = formState->values().begin(); it != end; ++it)
556         if (!it->first.isNull() && !it->second.isNull())
557             [dictionary setObject:it->second forKey:it->first];
558
559     [formDelegate frame:m_webFrame.get()
560             sourceFrame:kit(formState->sourceFrame())
561          willSubmitForm:kit(formState->form())
562              withValues:dictionary
563      submissionListener:setUpPolicyListener(function).get()];
564
565     [dictionary release];
566 }
567
568 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
569 {
570     if ([WebScriptDebugServer listenerCount])
571         [[WebScriptDebugServer sharedScriptDebugServer] webView:getWebView(m_webFrame.get())
572             didLoadMainResourceForDataSource:dataSource(loader)];
573 }
574
575 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
576 {
577     [dataSource(loader) _revertToProvisionalState];
578 }
579
580 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
581 {
582     [dataSource(loader) _setMainDocumentError:error];
583 }
584
585 void WebFrameLoaderClient::clearUnarchivingState(DocumentLoader* loader)
586 {
587     [dataSource(loader) _clearUnarchivingState];
588 }
589
590 void WebFrameLoaderClient::willChangeEstimatedProgress()
591 {
592     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
593 }
594
595 void WebFrameLoaderClient::didChangeEstimatedProgress()
596 {
597     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
598 }
599
600 void WebFrameLoaderClient::postProgressStartedNotification()
601 {
602     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
603 }
604
605 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
606 {
607     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
608 }
609
610 void WebFrameLoaderClient::postProgressFinishedNotification()
611 {
612     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
613 }
614
615 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
616 {
617     [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
618 }
619
620 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
621 {
622     // FIXME: Should download full request.
623     [getWebView(m_webFrame.get()) _downloadURL:request.url().getNSURL()];
624 }
625
626 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
627 {
628     // FIXME: Should do this only in main frame case, right?
629     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
630 }
631
632 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
633 {
634     // FIXME: Should do this only in main frame case, right?
635     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
636 }
637
638 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
639 {
640     NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
641     [dataSource(loader) _receivedData:nsData];
642     [nsData release];
643 }
644
645 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
646 {
647     [dataSource(loader) _finishedLoading];
648 }
649
650 void WebFrameLoaderClient::finalSetupForReplace(DocumentLoader* loader)
651 {
652     [dataSource(loader) _clearUnarchivingState];
653 }
654
655 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
656 // Once that task is complete, this will go away
657 void WebFrameLoaderClient::updateGlobalHistoryForStandardLoad(const KURL& url)
658 {
659     NSURL *nsurl = url.getNSURL();
660     WebHistoryItem *entry = [[WebHistory optionalSharedHistory] addItemForURL:nsurl];
661     String pageTitle = core(m_webFrame.get())->loader()->documentLoader()->title();
662     if (pageTitle.length())
663         [entry setTitle:pageTitle];
664 }
665  
666 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
667 // Once that task is complete, this will go away
668 void WebFrameLoaderClient::updateGlobalHistoryForReload(const KURL& url)
669 {
670     WebHistory *sharedHistory = [WebHistory optionalSharedHistory];
671     WebHistoryItem *item = [sharedHistory itemForURL:url.getNSURL()];
672     if (item)
673         [sharedHistory setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate] forItem:item];
674 }
675
676 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
677 {
678     WebView* view = getWebView(m_webFrame.get());
679     WebHistoryItem *webItem = kit(item);
680     
681     return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
682 }
683
684 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest &request)
685 {
686     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url().getNSURL()];
687 }
688
689 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
690 {
691     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url().getNSURL()];
692 }
693
694 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
695 {
696     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url().getNSURL()];
697 }
698
699 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
700 {
701     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url().getNSURL()];
702 }
703
704 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
705 {
706     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url().getNSURL()];    
707 }
708
709 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
710 {
711     // FIXME: Needs to check domain.
712     // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
713     // loading plugin content twice.  See <rdar://problem/4258008>
714     return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
715 }
716
717 void WebFrameLoaderClient::setDefersLoading(bool defers)
718 {
719     if (!defers)
720         deliverArchivedResourcesAfterDelay();
721 }
722
723 bool WebFrameLoaderClient::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const
724 {
725     if (request.url() != originalURL)
726         return false;
727     if (!canUseArchivedResource(request.nsURLRequest()))
728         return false;
729     WebResource *resource = [dataSource(core(m_webFrame.get())->loader()->activeDocumentLoader()) _archivedSubresourceForURL:originalURL.getNSURL()];
730     if (!resource)
731         return false;
732     if (!canUseArchivedResource([resource _response]))
733         return false;
734     m_pendingArchivedResources.set(loader, resource);
735     // Deliver the resource after a delay because callers don't expect to receive callbacks while calling this method.
736     deliverArchivedResourcesAfterDelay();
737     return true;
738 }
739
740 bool WebFrameLoaderClient::isArchiveLoadPending(ResourceLoader* loader) const
741 {
742     return m_pendingArchivedResources.contains(loader);
743 }
744
745 void WebFrameLoaderClient::cancelPendingArchiveLoad(ResourceLoader* loader)
746 {
747     if (m_pendingArchivedResources.isEmpty())
748         return;
749     m_pendingArchivedResources.remove(loader);
750     if (m_pendingArchivedResources.isEmpty())
751         m_archivedResourcesDeliveryTimer.stop();
752 }
753
754 void WebFrameLoaderClient::clearArchivedResources()
755 {
756     m_pendingArchivedResources.clear();
757     m_archivedResourcesDeliveryTimer.stop();
758 }
759
760 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
761 {
762     return [WebView _canHandleRequest:request.nsURLRequest()];
763 }
764
765 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
766 {
767     return [WebView canShowMIMEType:MIMEType];
768 }
769
770 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
771 {
772     return [WebView _representationExistsForURLScheme:URLScheme];
773 }
774
775 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
776 {
777     return [WebView _generatedMIMETypeForURLScheme:URLScheme];
778 }
779
780 void WebFrameLoaderClient::frameLoadCompleted()
781 {
782     // Note: Can be called multiple times.
783     // Even if already complete, we might have set a previous item on a frame that
784     // didn't do any data loading on the past transaction. Make sure to clear these out.
785     NSScrollView *sv = [m_webFrame->_private->webFrameView _scrollView];
786     if ([getWebView(m_webFrame.get()) drawsBackground])
787         [sv setDrawsBackground:YES];
788     core(m_webFrame.get())->loader()->setPreviousHistoryItem(0);
789 }
790
791
792 void WebFrameLoaderClient::saveScrollPositionAndViewStateToItem(HistoryItem* item)
793 {
794     if (!item)
795         return;
796     
797     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
798     NSView *parent = [docView superview];
799
800     // we might already be detached when this is called from detachFromParent, in which
801     // case we don't want to override real data earlier gathered with (0,0)
802     if (parent) {
803         NSPoint point;
804         if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
805             // The view has it's own idea of where it is scrolled to, perhaps because it contains its own
806             // ScrollView instead of using the one provided by the WebFrame
807             point = [(id <_WebDocumentViewState>)docView scrollPoint];
808             item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
809         } else {
810             // Parent is the clipview of the DynamicScrollView the WebFrame installs
811             ASSERT([parent isKindOfClass:[NSClipView class]]);
812             point = [parent bounds].origin;
813         }
814         item->setScrollPoint(IntPoint(point));
815     }
816 }
817
818 /*
819  There is a race condition between the layout and load completion that affects restoring the scroll position.
820  We try to restore the scroll position at both the first layout and upon load completion.
821  
822  1) If first layout happens before the load completes, we want to restore the scroll position then so that the
823  first time we draw the page is already scrolled to the right place, instead of starting at the top and later
824  jumping down.  It is possible that the old scroll position is past the part of the doc laid out so far, in
825  which case the restore silent fails and we will fix it in when we try to restore on doc completion.
826  2) If the layout happens after the load completes, the attempt to restore at load completion time silently
827  fails.  We then successfully restore it when the layout happens.
828 */
829 void WebFrameLoaderClient::restoreScrollPositionAndViewState()
830 {
831     HistoryItem* currentItem = core(m_webFrame.get())->loader()->currentHistoryItem();
832     ASSERT(currentItem);
833
834     // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
835     // One counterexample is <rdar://problem/4917290>
836     // For now, to cover this issue in release builds, there is no technical harm to returning
837     // early and from a user standpoint - as in the above radar - the previous page load failed 
838     // so there *is* no scroll state to restore!
839     if (!currentItem)
840         return;
841     
842     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
843     NSPoint point = currentItem->scrollPoint();
844     if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {        
845         id state = currentItem->viewState();
846         if (state) {
847             [(id <_WebDocumentViewState>)docView setViewState:state];
848         }
849         
850         [(id <_WebDocumentViewState>)docView setScrollPoint:point];
851     } else {
852         [docView scrollPoint:point];
853     }
854 }
855
856 void WebFrameLoaderClient::provisionalLoadStarted()
857 {    
858     // FIXME: This is OK as long as no one resizes the window,
859     // but in the case where someone does, it means garbage outside
860     // the occupied part of the scroll view.
861     [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:NO];
862 }
863
864 void WebFrameLoaderClient::didFinishLoad()
865 {
866     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];    
867 }
868
869 void WebFrameLoaderClient::prepareForDataSourceReplacement()
870 {
871     if (![m_webFrame.get() dataSource]) {
872         ASSERT(!core(m_webFrame.get())->tree()->childCount());
873         return;
874     }
875     
876     // Make sure that any work that is triggered by resigning first reponder can get done.
877     // The main example where this came up is the textDidEndEditing that is sent to the
878     // FormsDelegate (3223413).  We need to do this before _detachChildren, since that will
879     // remove the views as a side-effect of freeing the bridge, at which point we can't
880     // post the FormDelegate messages.
881     //
882     // Note that this can also take FirstResponder away from a child of our frameView that
883     // is not in a child frame's view.  This is OK because we are in the process
884     // of loading new content, which will blow away all editors in this top frame, and if
885     // a non-editor is firstReponder it will not be affected by endEditingFor:.
886     // Potentially one day someone could write a DocView whose editors were not all
887     // replaced by loading new content, but that does not apply currently.
888     NSView *frameView = m_webFrame->_private->webFrameView;
889     NSWindow *window = [frameView window];
890     NSResponder *firstResp = [window firstResponder];
891     if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
892         [window endEditingFor:firstResp];
893     
894     core(m_webFrame.get())->loader()->detachChildren();
895 }
896
897 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request)
898 {
899     RefPtr<WebDocumentLoaderMac> loader = new WebDocumentLoaderMac(request);
900
901     WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
902     loader->setDataSource(dataSource);
903     [dataSource release];
904
905     return loader.release();
906 }
907
908 // FIXME: <rdar://problem/4880065> - Push Global History into WebCore
909 // Once that task is complete, this will go away
910 void WebFrameLoaderClient::setTitle(const String& title, const KURL& URL)
911 {
912     NSURL* nsURL = canonicalURL(URL.getNSURL());
913     if(!nsURL)
914         return;
915     NSString *titleNSString = title;
916     [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
917     if (HistoryItem* item = core(m_webFrame.get())->loader()->currentHistoryItem())
918         item->setTitle(title);
919 }
920
921 // The following 2 functions are copied from [NSHTTPURLProtocol _cachedResponsePassesValidityChecks] and modified for our needs.
922 // FIXME: It would be nice to eventually to share this logic somehow.
923 bool WebFrameLoaderClient::canUseArchivedResource(NSURLRequest *request) const
924 {
925     NSURLRequestCachePolicy policy = [request cachePolicy];
926     if (policy == NSURLRequestReturnCacheDataElseLoad)
927         return true;
928     if (policy == NSURLRequestReturnCacheDataDontLoad)
929         return true;
930     if (policy == NSURLRequestReloadIgnoringCacheData)
931         return false;
932     if ([request valueForHTTPHeaderField:@"must-revalidate"] != nil)
933         return false;
934     if ([request valueForHTTPHeaderField:@"proxy-revalidate"] != nil)
935         return false;
936     if ([request valueForHTTPHeaderField:@"If-Modified-Since"] != nil)
937         return false;
938     if ([request valueForHTTPHeaderField:@"Cache-Control"] != nil)
939         return false;
940     if ([@"POST" _webkit_isCaseInsensitiveEqualToString:[request HTTPMethod]])
941         return false;
942     return true;
943 }
944
945 bool WebFrameLoaderClient::canUseArchivedResource(NSURLResponse *response) const
946 {
947     if (WKGetNSURLResponseMustRevalidate(response))
948         return false;
949     if (WKGetNSURLResponseCalculatedExpiration(response) - CFAbsoluteTimeGetCurrent() < 1)
950         return false;
951     return true;
952 }
953
954 void WebFrameLoaderClient::deliverArchivedResourcesAfterDelay() const
955 {
956     if (m_pendingArchivedResources.isEmpty())
957         return;
958     if (core(m_webFrame.get())->page()->defersLoading())
959         return;
960     if (!m_archivedResourcesDeliveryTimer.isActive())
961         m_archivedResourcesDeliveryTimer.startOneShot(0);
962 }
963
964 void WebFrameLoaderClient::deliverArchivedResources(Timer<WebFrameLoaderClient>*)
965 {
966     if (m_pendingArchivedResources.isEmpty())
967         return;
968     if (core(m_webFrame.get())->page()->defersLoading())
969         return;
970
971     const ResourceMap copy = m_pendingArchivedResources;
972     m_pendingArchivedResources.clear();
973
974     ResourceMap::const_iterator end = copy.end();
975     for (ResourceMap::const_iterator it = copy.begin(); it != end; ++it) {
976         RefPtr<ResourceLoader> loader = it->first;
977         WebResource *resource = it->second.get();
978         NSData *data = [[resource data] retain];
979         loader->didReceiveResponse([resource _response]);
980         loader->didReceiveData((const char*)[data bytes], [data length], [data length], true);
981         [data release];
982         loader->didFinishLoading();
983     }
984 }
985
986 void WebFrameLoaderClient::saveDocumentViewToPageCache(PageCache* pageCache)
987 {
988     pageCache->setDocumentView([m_webFrame->_private->webFrameView documentView]);
989 }
990
991 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
992 {
993     ASSERT(!m_policyListener);
994     ASSERT(!m_policyFunction);
995
996     [m_policyListener.get() invalidate];
997
998     WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
999     m_policyListener = listener;
1000     [listener release];
1001     m_policyFunction = function;
1002
1003     return listener;
1004 }
1005
1006 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1007 {
1008     ASSERT(m_policyListener);
1009     ASSERT(m_policyFunction);
1010
1011     FramePolicyFunction function = m_policyFunction;
1012
1013     m_policyListener = nil;
1014     m_policyFunction = 0;
1015
1016     (core(m_webFrame.get())->loader()->*function)(action);
1017 }
1018
1019 String WebFrameLoaderClient::userAgent()
1020 {
1021     return [getWebView(m_webFrame.get()) _userAgent];
1022 }
1023
1024 static const MouseEvent* findMouseEvent(const Event* event)
1025 {
1026     for (const Event* e = event; e; e = e->underlyingEvent())
1027         if (e->isMouseEvent())
1028             return static_cast<const MouseEvent*>(e);
1029     return 0;
1030 }
1031
1032 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action) const
1033 {
1034     unsigned modifierFlags = 0;
1035     const Event* event = action.event();
1036     if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1037         if (keyStateEvent->ctrlKey())
1038             modifierFlags |= NSControlKeyMask;
1039         if (keyStateEvent->altKey())
1040             modifierFlags |= NSAlternateKeyMask;
1041         if (keyStateEvent->shiftKey())
1042             modifierFlags |= NSShiftKeyMask;
1043         if (keyStateEvent->metaKey())
1044             modifierFlags |= NSCommandKeyMask;
1045     }
1046     if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1047         IntPoint point(mouseEvent->clientX(), mouseEvent->clientY());
1048         WebElementDictionary *element = [[WebElementDictionary alloc]
1049             initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(point, false)];
1050         NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:
1051             [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1052             element, WebActionElementKey,
1053             [NSNumber numberWithInt:mouseEvent->button()], WebActionButtonKey,
1054             [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1055             action.URL().getNSURL(), WebActionOriginalURLKey,
1056             nil];
1057         [element release];
1058         return result;
1059     }
1060     return [NSDictionary dictionaryWithObjectsAndKeys:
1061         [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1062         [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1063         action.URL().getNSURL(), WebActionOriginalURLKey,
1064         nil];
1065 }
1066
1067 bool WebFrameLoaderClient::canCachePage() const
1068 {
1069     // We can only cache HTML pages right now
1070     return [[[m_webFrame.get() dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1071 }
1072
1073 Frame* WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1074                                          const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1075 {
1076     WebFrameBridge* bridge = m_webFrame->_private->bridge;
1077     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1078     
1079     return [bridge createChildFrameNamed:name
1080                    withURL:url.getNSURL()
1081                    referrer:referrer 
1082                    ownerElement:ownerElement
1083                    allowsScrolling:allowsScrolling
1084                    marginWidth:marginWidth
1085                    marginHeight:marginHeight];
1086
1087     END_BLOCK_OBJC_EXCEPTIONS;
1088     return 0;
1089 }
1090
1091 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType)
1092 {
1093     WebFrameBridge* bridge = m_webFrame->_private->bridge;
1094     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1095     return (ObjectContentType)[bridge determineObjectFromMIMEType:mimeType URL:url.getNSURL()];
1096     END_BLOCK_OBJC_EXCEPTIONS;
1097     return ObjectContentNone;
1098 }
1099
1100 static NSArray* nsArray(const Vector<String>& vector)
1101 {
1102     unsigned len = vector.size();
1103     NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1104     for (unsigned x = 0; x < len; x++)
1105         [array addObject:vector[x]];
1106     return array;
1107 }
1108
1109 Widget* WebFrameLoaderClient::createPlugin(Element* element, const KURL& url, const Vector<String>& paramNames,
1110                                            const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1111 {
1112     WebFrameBridge* bridge = m_webFrame->_private->bridge;
1113
1114     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1115     return new Widget([bridge viewForPluginWithURL:url.getNSURL()
1116                               attributeNames:nsArray(paramNames)
1117                               attributeValues:nsArray(paramValues)
1118                               MIMEType:mimeType
1119                               DOMElement:[DOMElement _elementWith:element]
1120                               loadManually:loadManually]);
1121     END_BLOCK_OBJC_EXCEPTIONS;
1122
1123     return 0;
1124 }
1125
1126 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1127 {
1128     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1129     [m_webFrame->_private->bridge redirectDataToPlugin:pluginWidget->getView()];
1130     END_BLOCK_OBJC_EXCEPTIONS;
1131 }
1132
1133 WebCore::Widget* WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, Element* element, const KURL& baseURL, 
1134                                                               const Vector<String>& paramNames, const Vector<String>& paramValues)
1135 {
1136     Widget* result = new Widget;
1137     
1138     BEGIN_BLOCK_OBJC_EXCEPTIONS;
1139     WebFrameBridge* bridge = m_webFrame->_private->bridge;
1140     result->setView([bridge viewForJavaAppletWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1141                             attributeNames:nsArray(paramNames)
1142                             attributeValues:nsArray(paramValues)
1143                             baseURL:baseURL.getNSURL()
1144                             DOMElement:[DOMElement _elementWith:element]]);    
1145     END_BLOCK_OBJC_EXCEPTIONS;
1146     
1147     return result;
1148 }
1149
1150 String WebFrameLoaderClient::overrideMediaType() const
1151 {
1152     NSString* overrideType = [m_webFrame->_private->bridge overrideMediaType];
1153     if (overrideType)
1154         return overrideType;
1155     return String();
1156 }
1157
1158 void WebFrameLoaderClient::windowObjectCleared() const
1159 {
1160     [m_webFrame->_private->bridge windowObjectCleared];
1161 }
1162
1163 @implementation WebFramePolicyListener
1164
1165 - (id)initWithWebCoreFrame:(Frame*)frame
1166 {
1167     self = [self init];
1168     if (!self)
1169         return nil;
1170     frame->ref();
1171     m_frame = frame;
1172     return self;
1173 }
1174
1175 - (void)invalidate
1176 {
1177     if (m_frame) {
1178         m_frame->deref();
1179         m_frame = 0;
1180     }
1181 }
1182
1183 - (void)dealloc
1184 {
1185     if (m_frame)
1186         m_frame->deref();
1187     [super dealloc];
1188 }
1189
1190 - (void)finalize
1191 {
1192     if (m_frame)
1193         m_frame->deref();
1194     [super finalize];
1195 }
1196
1197 - (void)receivedPolicyDecision:(PolicyAction)action
1198 {
1199     RefPtr<Frame> frame = adoptRef(m_frame);
1200     m_frame = 0;
1201     if (frame)
1202         static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
1203 }
1204
1205 - (void)ignore
1206 {
1207     [self receivedPolicyDecision:PolicyIgnore];
1208 }
1209
1210 - (void)download
1211 {
1212     [self receivedPolicyDecision:PolicyDownload];
1213 }
1214
1215 - (void)use
1216 {
1217     [self receivedPolicyDecision:PolicyUse];
1218 }
1219
1220 - (void)continue
1221 {
1222     [self receivedPolicyDecision:PolicyUse];
1223 }
1224
1225
1226
1227 @end