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