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