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