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