2 * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
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.
29 #import "WebFrameLoaderClient.h"
31 // Terrible hack; lets us get at the WebFrame private structure.
32 #define private public
36 #import "DOMElementInternal.h"
37 #import "WebBackForwardList.h"
38 #import "WebCachedFramePlatformData.h"
39 #import "WebChromeClient.h"
40 #import "WebDataSourceInternal.h"
41 #import "WebDelegateImplementationCaching.h"
42 #import "WebDocumentInternal.h"
43 #import "WebDocumentLoaderMac.h"
44 #import "WebDownloadInternal.h"
45 #import "WebDynamicScrollBarsViewInternal.h"
46 #import "WebElementDictionary.h"
47 #import "WebFormDelegate.h"
48 #import "WebFrameInternal.h"
49 #import "WebFrameLoadDelegate.h"
50 #import "WebFrameNetworkingContext.h"
51 #import "WebFrameViewInternal.h"
52 #import "WebHTMLRepresentationPrivate.h"
53 #import "WebHTMLViewInternal.h"
54 #import "WebHistoryInternal.h"
55 #import "WebHistoryItemInternal.h"
56 #import "WebIconDatabaseInternal.h"
57 #import "WebKitErrorsPrivate.h"
58 #import "WebKitLogging.h"
59 #import "WebKitNSStringExtras.h"
60 #import "WebNSURLExtras.h"
61 #import "WebNavigationData.h"
62 #import "WebNetscapePluginPackage.h"
63 #import "WebNetscapePluginView.h"
64 #import "WebPanelAuthenticationHandler.h"
65 #import "WebPluginController.h"
66 #import "WebPluginPackage.h"
67 #import "WebPluginViewFactoryPrivate.h"
68 #import "WebPolicyDelegate.h"
69 #import "WebPolicyDelegatePrivate.h"
70 #import "WebPreferences.h"
71 #import "WebResourceLoadDelegate.h"
72 #import "WebScriptWorldInternal.h"
73 #import "WebSecurityOriginInternal.h"
74 #import "WebUIDelegate.h"
75 #import "WebUIDelegatePrivate.h"
76 #import "WebViewInternal.h"
77 #import <WebCore/AuthenticationCF.h>
78 #import <WebCore/AuthenticationMac.h>
79 #import <WebCore/BackForwardController.h>
80 #import <WebCore/BlockExceptions.h>
81 #import <WebCore/CachedFrame.h>
82 #import <WebCore/Chrome.h>
83 #import <WebCore/Document.h>
84 #import <WebCore/DocumentLoader.h>
85 #import <WebCore/EventHandler.h>
86 #import <WebCore/FocusController.h>
87 #import <WebCore/FormState.h>
88 #import <WebCore/Frame.h>
89 #import <WebCore/FrameLoader.h>
90 #import <WebCore/FrameLoaderStateMachine.h>
91 #import <WebCore/FrameLoaderTypes.h>
92 #import <WebCore/FrameTree.h>
93 #import <WebCore/FrameView.h>
94 #import <WebCore/HTMLAppletElement.h>
95 #import <WebCore/HTMLFormElement.h>
96 #import <WebCore/HTMLFrameElement.h>
97 #import <WebCore/HTMLFrameOwnerElement.h>
98 #import <WebCore/HTMLHeadElement.h>
99 #import <WebCore/HTMLNames.h>
100 #import <WebCore/HTMLParserIdioms.h>
101 #import <WebCore/HTMLPlugInElement.h>
102 #import <WebCore/HistoryItem.h>
103 #import <WebCore/HitTestResult.h>
104 #import <WebCore/IconDatabase.h>
105 #import <WebCore/LoaderNSURLExtras.h>
106 #import <WebCore/MIMETypeRegistry.h>
107 #import <WebCore/MainResourceLoader.h>
108 #import <WebCore/MouseEvent.h>
109 #import <WebCore/Page.h>
110 #import <WebCore/PluginViewBase.h>
111 #import <WebCore/ProtectionSpace.h>
112 #import <WebCore/ResourceError.h>
113 #import <WebCore/ResourceHandle.h>
114 #import <WebCore/ResourceLoader.h>
115 #import <WebCore/ResourceRequest.h>
116 #import <WebCore/RunLoop.h>
117 #import <WebCore/ScriptController.h>
118 #import <WebCore/SharedBuffer.h>
119 #import <WebCore/WebCoreObjCExtras.h>
120 #import <WebCore/Widget.h>
121 #import <WebKit/DOMElement.h>
122 #import <WebKit/DOMHTMLFormElement.h>
123 #import <WebKitSystemInterface.h>
124 #import <runtime/InitializeThreading.h>
125 #import <wtf/MainThread.h>
126 #import <wtf/PassRefPtr.h>
127 #import <wtf/text/WTFString.h>
129 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
130 #import <WebCore/HTMLMediaElement.h>
133 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
134 #import "NetscapePluginHostManager.h"
135 #import "WebHostedNetscapePluginView.h"
138 using namespace WebCore;
139 using namespace HTMLNames;
142 // For backwards compatibility with older WebKit plug-ins.
143 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
144 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
145 NSString *WebPluginContainerKey = @"WebPluginContainer";
147 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> {
150 - (id)initWithWebCoreFrame:(Frame*)frame;
154 static inline WebDataSource *dataSource(DocumentLoader* loader)
156 return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
159 // Quirk for the Apple Dictionary application.
161 // If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,
162 // then for that frame's document, ignore changes to the scrolling attribute of frames. That script
163 // has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling
164 // attribute needs to be ignored to avoid showing extra scroll bars in the window.
165 // This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).
167 static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request)
169 if (!request.url().isLocalFile())
171 if (!request.url().string().endsWith("MainPageJavaScript.js"))
173 Frame* frame = core(client->webFrame());
176 if (frame->tree()->parent())
178 Document* document = frame->document();
181 HTMLHeadElement* head = document->head();
184 for (Node* c = head->firstChild(); c; c = c->nextSibling()) {
185 if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") {
186 document->setFrameElementsShouldIgnoreScrolling(true);
192 static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request)
194 // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in
195 // all applications other than Apple Dictionary.
196 static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"];
197 if (isAppleDictionary)
198 applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);
201 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
202 : m_webFrame(webFrame)
203 , m_policyFunction(0)
207 void WebFrameLoaderClient::frameLoaderDestroyed()
209 [m_webFrame.get() _clearCoreFrame];
213 bool WebFrameLoaderClient::hasWebView() const
215 return [m_webFrame.get() webView] != nil;
218 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
220 [dataSource(loader) _makeRepresentation];
223 bool WebFrameLoaderClient::hasHTMLView() const
225 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
226 return [view isKindOfClass:[WebHTMLView class]];
229 void WebFrameLoaderClient::forceLayout()
231 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
232 [view setNeedsLayout:YES];
236 void WebFrameLoaderClient::forceLayoutForNonHTML()
238 WebFrameView *thisView = m_webFrame->_private->webFrameView;
239 NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
240 ASSERT(thisDocumentView != nil);
242 // Tell the just loaded document to layout. This may be necessary
243 // for non-html content that needs a layout message.
244 if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) {
245 [thisDocumentView setNeedsLayout:YES];
246 [thisDocumentView layout];
247 [thisDocumentView setNeedsDisplay:YES];
251 void WebFrameLoaderClient::setCopiesOnScroll()
253 [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
256 void WebFrameLoaderClient::detachedFromParent2()
258 //remove any NetScape plugins that are children of this frame because they are about to be detached
259 WebView *webView = getWebView(m_webFrame.get());
260 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
261 [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
263 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
264 if (implementations->didRemoveFrameFromHierarchyFunc)
265 CallFrameLoadDelegate(implementations->didRemoveFrameFromHierarchyFunc, webView, @selector(webView:didRemoveFrameFromHierarchy:), m_webFrame.get());
268 void WebFrameLoaderClient::detachedFromParent3()
270 [m_webFrame->_private->webFrameView release];
271 m_webFrame->_private->webFrameView = nil;
274 void WebFrameLoaderClient::convertMainResourceLoadToDownload(MainResourceLoader* mainResourceLoader, const ResourceRequest& request, const ResourceResponse& response)
276 ResourceHandle* handle = mainResourceLoader->loader()->handle();
279 ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
280 WebView *webView = getWebView(m_webFrame.get());
281 CFURLConnectionRef connection = handle->connection();
282 [WebDownload _downloadWithLoadingCFURLConnection:connection
283 request:request.cfURLRequest()
284 response:response.cfURLResponse()
285 delegate:[webView downloadDelegate]
288 // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
289 handle->releaseConnectionForDownload();
290 CFRelease(connection);
292 id proxy = handle->releaseProxy();
295 WebView *webView = getWebView(m_webFrame.get());
296 [WebDownload _downloadWithLoadingConnection:handle->connection()
297 request:request.nsURLRequest()
298 response:response.nsURLResponse()
299 delegate:[webView downloadDelegate]
304 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
306 applyAppleDictionaryApplicationQuirk(this, request);
308 WebView *webView = getWebView(m_webFrame.get());
309 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
310 if (!implementations->didLoadResourceFromMemoryCacheFunc)
313 CallResourceLoadDelegate(implementations->didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
317 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
319 WebView *webView = getWebView(m_webFrame.get());
320 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
323 BOOL shouldRelease = NO;
324 if (implementations->identifierForRequestFunc)
325 object = CallResourceLoadDelegate(implementations->identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
327 object = [[NSObject alloc] init];
331 [webView _addObject:object forIdentifier:identifier];
337 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
339 applyAppleDictionaryApplicationQuirk(this, request);
341 WebView *webView = getWebView(m_webFrame.get());
342 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
344 if (redirectResponse.isNull())
345 static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
347 NSURLRequest *currentURLRequest = request.nsURLRequest();
348 NSURLRequest *newURLRequest = currentURLRequest;
349 if (implementations->willSendRequestFunc)
350 newURLRequest = (NSURLRequest *)CallResourceLoadDelegate(implementations->willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], currentURLRequest, redirectResponse.nsURLResponse(), dataSource(loader));
352 if (newURLRequest != currentURLRequest)
353 request = newURLRequest;
356 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
358 WebView *webView = getWebView(m_webFrame.get());
359 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
361 if (implementations->shouldUseCredentialStorageFunc) {
362 if (id resource = [webView _objectForIdentifier:identifier])
363 return CallResourceLoadDelegateReturningBoolean(NO, implementations->shouldUseCredentialStorageFunc, webView, @selector(webView:resource:shouldUseCredentialStorageForDataSource:), resource, dataSource(loader));
369 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
371 WebView *webView = getWebView(m_webFrame.get());
372 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
374 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
376 if (implementations->didReceiveAuthenticationChallengeFunc) {
377 if (id resource = [webView _objectForIdentifier:identifier]) {
378 CallResourceLoadDelegate(implementations->didReceiveAuthenticationChallengeFunc, webView, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
383 NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
384 [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
387 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
388 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader* loader, unsigned long identifier, const ProtectionSpace& protectionSpace)
390 WebView *webView = getWebView(m_webFrame.get());
391 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
393 NSURLProtectionSpace *webProtectionSpace = mac(protectionSpace);
395 if (implementations->canAuthenticateAgainstProtectionSpaceFunc) {
396 if (id resource = [webView _objectForIdentifier:identifier]) {
397 return CallResourceLoadDelegateReturningBoolean(NO, implementations->canAuthenticateAgainstProtectionSpaceFunc, webView, @selector(webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:), resource, webProtectionSpace, dataSource(loader));
401 // If our resource load delegate doesn't handle the question, then only send authentication
402 // challenges for pre-10.6 protection spaces. This is the same as the default implementation
404 return (protectionSpace.authenticationScheme() < ProtectionSpaceAuthenticationSchemeClientCertificateRequested);
408 bool WebFrameLoaderClient::shouldPaintBrokenImage(const KURL& imageURL) const
410 WebView *webView = getWebView(m_webFrame.get());
411 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
413 if (implementations->shouldPaintBrokenImageForURLFunc) {
414 NSURL* url = imageURL;
415 return CallResourceLoadDelegateReturningBoolean(YES, implementations->shouldPaintBrokenImageForURLFunc, webView, @selector(webView:shouldPaintBrokenImageForURL:), url);
420 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
422 WebView *webView = getWebView(m_webFrame.get());
423 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
424 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
426 if (implementations->didCancelAuthenticationChallengeFunc) {
427 if (id resource = [webView _objectForIdentifier:identifier]) {
428 CallResourceLoadDelegate(implementations->didCancelAuthenticationChallengeFunc, webView, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
433 [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
436 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
438 WebView *webView = getWebView(m_webFrame.get());
439 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
440 if (implementations->didReceiveResponseFunc) {
441 if (id resource = [webView _objectForIdentifier:identifier])
442 CallResourceLoadDelegate(implementations->didReceiveResponseFunc, webView, @selector(webView:resource:didReceiveResponse:fromDataSource:), resource, response.nsURLResponse(), dataSource(loader));
446 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loader, unsigned long identifier, NSCachedURLResponse* response) const
448 WebView *webView = getWebView(m_webFrame.get());
449 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
451 if (implementations->willCacheResponseFunc) {
452 if (id resource = [webView _objectForIdentifier:identifier])
453 return CallResourceLoadDelegate(implementations->willCacheResponseFunc, webView, @selector(webView:resource:willCacheResponse:fromDataSource:), resource, response, dataSource(loader));
459 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int dataLength)
461 WebView *webView = getWebView(m_webFrame.get());
462 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
463 if (implementations->didReceiveContentLengthFunc) {
464 if (id resource = [webView _objectForIdentifier:identifier])
465 CallResourceLoadDelegate(implementations->didReceiveContentLengthFunc, webView, @selector(webView:resource:didReceiveContentLength:fromDataSource:), resource, (NSInteger)dataLength, dataSource(loader));
469 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
471 WebView *webView = getWebView(m_webFrame.get());
472 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
474 if (implementations->didFinishLoadingFromDataSourceFunc) {
475 if (id resource = [webView _objectForIdentifier:identifier])
476 CallResourceLoadDelegate(implementations->didFinishLoadingFromDataSourceFunc, webView, @selector(webView:resource:didFinishLoadingFromDataSource:), resource, dataSource(loader));
479 [webView _removeObjectForIdentifier:identifier];
481 static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
484 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
486 WebView *webView = getWebView(m_webFrame.get());
487 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
489 if (implementations->didFailLoadingWithErrorFromDataSourceFunc) {
490 if (id resource = [webView _objectForIdentifier:identifier])
491 CallResourceLoadDelegate(implementations->didFailLoadingWithErrorFromDataSourceFunc, webView, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), resource, (NSError *)error, dataSource(loader));
494 [webView _removeObjectForIdentifier:identifier];
496 static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
499 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
501 WebView *webView = getWebView(m_webFrame.get());
502 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
503 if (implementations->didHandleOnloadEventsForFrameFunc)
504 CallFrameLoadDelegate(implementations->didHandleOnloadEventsForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
507 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
509 WebView *webView = getWebView(m_webFrame.get());
510 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
511 if (implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc)
512 CallFrameLoadDelegate(implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc, webView, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:), m_webFrame.get());
515 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
517 WebView *webView = getWebView(m_webFrame.get());
518 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
519 if (implementations->didCancelClientRedirectForFrameFunc)
520 CallFrameLoadDelegate(implementations->didCancelClientRedirectForFrameFunc, webView, @selector(webView:didCancelClientRedirectForFrame:), m_webFrame.get());
523 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
525 WebView *webView = getWebView(m_webFrame.get());
526 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
527 if (implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc) {
528 NSURL *cocoaURL = url;
529 CallFrameLoadDelegate(implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc, webView, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), cocoaURL, delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
533 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
535 WebView *webView = getWebView(m_webFrame.get());
536 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
537 if (implementations->didChangeLocationWithinPageForFrameFunc)
538 CallFrameLoadDelegate(implementations->didChangeLocationWithinPageForFrameFunc, webView, @selector(webView:didChangeLocationWithinPageForFrame:), m_webFrame.get());
541 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
543 WebView *webView = getWebView(m_webFrame.get());
544 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
545 if (implementations->didPushStateWithinPageForFrameFunc)
546 CallFrameLoadDelegate(implementations->didPushStateWithinPageForFrameFunc, webView, @selector(webView:didPushStateWithinPageForFrame:), m_webFrame.get());
549 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
551 WebView *webView = getWebView(m_webFrame.get());
552 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
553 if (implementations->didReplaceStateWithinPageForFrameFunc)
554 CallFrameLoadDelegate(implementations->didReplaceStateWithinPageForFrameFunc, webView, @selector(webView:didReplaceStateWithinPageForFrame:), m_webFrame.get());
557 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
559 WebView *webView = getWebView(m_webFrame.get());
560 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
561 if (implementations->didPopStateWithinPageForFrameFunc)
562 CallFrameLoadDelegate(implementations->didPopStateWithinPageForFrameFunc, webView, @selector(webView:didPopStateWithinPageForFrame:), m_webFrame.get());
565 void WebFrameLoaderClient::dispatchWillClose()
567 WebView *webView = getWebView(m_webFrame.get());
568 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
569 if (implementations->willCloseFrameFunc)
570 CallFrameLoadDelegate(implementations->willCloseFrameFunc, webView, @selector(webView:willCloseFrame:), m_webFrame.get());
573 void WebFrameLoaderClient::dispatchDidReceiveIcon()
575 #if ENABLE(ICONDATABASE)
576 WebView *webView = getWebView(m_webFrame.get());
577 ASSERT(m_webFrame == [webView mainFrame]);
578 [webView _dispatchDidReceiveIconFromWebFrame:m_webFrame.get()];
582 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
584 WebView *webView = getWebView(m_webFrame.get());
585 [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
587 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
588 if (implementations->didStartProvisionalLoadForFrameFunc)
589 CallFrameLoadDelegate(implementations->didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
592 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
594 WebView *webView = getWebView(m_webFrame.get());
595 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
596 if (implementations->didReceiveTitleForFrameFunc)
597 // FIXME: use direction of title.
598 CallFrameLoadDelegate(implementations->didReceiveTitleForFrameFunc, webView, @selector(webView:didReceiveTitle:forFrame:), (NSString *)title.string(), m_webFrame.get());
601 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
603 // FIXME: Implement this to allow container to update favicon.
606 void WebFrameLoaderClient::dispatchDidCommitLoad()
608 // Tell the client we've committed this URL.
609 ASSERT([m_webFrame->_private->webFrameView documentView] != nil);
611 WebView *webView = getWebView(m_webFrame.get());
612 [webView _didCommitLoadForFrame:m_webFrame.get()];
614 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
615 if (implementations->didCommitLoadForFrameFunc)
616 CallFrameLoadDelegate(implementations->didCommitLoadForFrameFunc, webView, @selector(webView:didCommitLoadForFrame:), m_webFrame.get());
619 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
621 WebView *webView = getWebView(m_webFrame.get());
622 [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
624 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
625 if (implementations->didFailProvisionalLoadWithErrorForFrameFunc)
626 CallFrameLoadDelegate(implementations->didFailProvisionalLoadWithErrorForFrameFunc, webView, @selector(webView:didFailProvisionalLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
628 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
631 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
633 WebView *webView = getWebView(m_webFrame.get());
634 [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
636 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
637 if (implementations->didFailLoadWithErrorForFrameFunc)
638 CallFrameLoadDelegate(implementations->didFailLoadWithErrorForFrameFunc, webView, @selector(webView:didFailLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
640 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
643 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
645 WebView *webView = getWebView(m_webFrame.get());
646 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
647 if (implementations->didFinishDocumentLoadForFrameFunc)
648 CallFrameLoadDelegate(implementations->didFinishDocumentLoadForFrameFunc, webView, @selector(webView:didFinishDocumentLoadForFrame:), m_webFrame.get());
651 void WebFrameLoaderClient::dispatchDidFinishLoad()
653 WebView *webView = getWebView(m_webFrame.get());
654 [webView _didFinishLoadForFrame:m_webFrame.get()];
656 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
657 if (implementations->didFinishLoadForFrameFunc)
658 CallFrameLoadDelegate(implementations->didFinishLoadForFrameFunc, webView, @selector(webView:didFinishLoadForFrame:), m_webFrame.get());
660 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
663 void WebFrameLoaderClient::dispatchDidLayout(LayoutMilestones milestones)
665 WebView *webView = getWebView(m_webFrame.get());
666 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
668 if (implementations->didLayoutFunc)
669 CallFrameLoadDelegate(implementations->didLayoutFunc, webView, @selector(webView:didLayout:), kitLayoutMilestones(milestones));
671 if (milestones & DidFirstLayout) {
672 // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
673 // new didLayout API.
674 if (implementations->didFirstLayoutInFrameFunc)
675 CallFrameLoadDelegate(implementations->didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
677 // See WebFrameLoaderClient::provisionalLoadStarted.
678 WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
679 if ([getWebView(m_webFrame.get()) drawsBackground])
680 [scrollView setDrawsBackground:YES];
681 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
682 [scrollView setVerticalScrollElasticity:NSScrollElasticityAutomatic];
683 [scrollView setHorizontalScrollElasticity:NSScrollElasticityAutomatic];
687 if (milestones & DidFirstVisuallyNonEmptyLayout) {
688 // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
689 // double duty with the new didLayout API.
690 if (implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc)
691 CallFrameLoadDelegate(implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc, webView, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:), m_webFrame.get());
695 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
697 WebView *currentWebView = getWebView(m_webFrame.get());
698 NSDictionary *features = [[NSDictionary alloc] init];
699 WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView
700 createWebViewWithRequest:nil
701 windowFeatures:features];
704 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
706 WebKit::NetscapePluginHostManager::shared().didCreateWindow();
709 return core([newWebView mainFrame]);
712 void WebFrameLoaderClient::dispatchShow()
714 WebView *webView = getWebView(m_webFrame.get());
715 [[webView _UIDelegateForwarder] webViewShow:webView];
718 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function,
719 const ResourceResponse& response, const ResourceRequest& request)
721 WebView *webView = getWebView(m_webFrame.get());
723 [[webView _policyDelegateForwarder] webView:webView
724 decidePolicyForMIMEType:response.mimeType()
725 request:request.nsURLRequest()
726 frame:m_webFrame.get()
727 decisionListener:setUpPolicyListener(function).get()];
730 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
731 const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
733 WebView *webView = getWebView(m_webFrame.get());
734 [[webView _policyDelegateForwarder] webView:webView
735 decidePolicyForNewWindowAction:actionDictionary(action, formState)
736 request:request.nsURLRequest()
737 newFrameName:frameName
738 decisionListener:setUpPolicyListener(function).get()];
741 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
742 const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
744 WebView *webView = getWebView(m_webFrame.get());
745 [[webView _policyDelegateForwarder] webView:webView
746 decidePolicyForNavigationAction:actionDictionary(action, formState)
747 request:request.nsURLRequest()
748 frame:m_webFrame.get()
749 decisionListener:setUpPolicyListener(function).get()];
752 void WebFrameLoaderClient::cancelPolicyCheck()
754 [m_policyListener.get() invalidate];
755 m_policyListener = nil;
756 m_policyFunction = 0;
759 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
761 WebView *webView = getWebView(m_webFrame.get());
762 [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];
765 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
767 id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
769 (core(m_webFrame.get())->loader()->policyChecker()->*function)(PolicyUse);
773 const StringPairVector& textFieldValues = formState->textFieldValues();
774 size_t size = textFieldValues.size();
775 NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:size];
776 for (size_t i = 0; i < size; ++i)
777 [dictionary setObject:textFieldValues[i].second forKey:textFieldValues[i].first];
779 CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceDocument()->frame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
781 [dictionary release];
784 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
786 [dataSource(loader) _revertToProvisionalState];
789 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
791 [dataSource(loader) _setMainDocumentError:error];
794 void WebFrameLoaderClient::willChangeEstimatedProgress()
796 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
799 void WebFrameLoaderClient::didChangeEstimatedProgress()
801 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
804 void WebFrameLoaderClient::postProgressStartedNotification()
806 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
809 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
811 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
814 void WebFrameLoaderClient::postProgressFinishedNotification()
816 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
819 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
821 [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
824 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
826 // FIXME: Should download full request.
827 [getWebView(m_webFrame.get()) _downloadURL:request.url()];
830 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
832 // FIXME: Should do this only in main frame case, right?
833 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
836 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
838 // FIXME: Should do this only in main frame case, right?
839 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
842 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
844 NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
845 [dataSource(loader) _receivedData:nsData];
849 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
851 [dataSource(loader) _finishedLoading];
854 void WebFrameLoaderClient::updateGlobalHistory()
856 WebView* view = getWebView(m_webFrame.get());
857 DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
859 if ([view historyDelegate]) {
860 WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
861 if (implementations->navigatedFunc) {
862 WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->urlForHistory()
863 title:loader->title().string()
864 originalRequest:loader->originalRequestCopy().nsURLRequest()
865 response:loader->response().nsURLResponse()
866 hasSubstituteData:loader->substituteData().isValid()
867 clientRedirectSource:loader->clientRedirectSourceForHistory()];
869 CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
876 [[WebHistory optionalSharedHistory] _visitedURL:loader->urlForHistory()
877 withTitle:loader->title().string()
878 method:loader->originalRequestCopy().httpMethod()
879 wasFailure:loader->urlForHistoryReflectsFailure()
880 increaseVisitCount:!loader->clientRedirectSourceForHistory()]; // Do not increase visit count due to navigations that were not initiated by the user directly, avoiding growth from programmatic reloads.
883 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
885 WebView* view = getWebView(m_webFrame.get());
886 WebHistoryDelegateImplementationCache* implementations = [view historyDelegate] ? WebViewGetHistoryDelegateImplementations(view) : 0;
888 DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
889 ASSERT(loader->unreachableURL().isEmpty());
891 if (!loader->clientRedirectSourceForHistory().isNull()) {
892 if (implementations) {
893 if (implementations->clientRedirectFunc) {
894 CallHistoryDelegate(implementations->clientRedirectFunc, view, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:),
895 loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_webFrame.get());
897 } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->clientRedirectSourceForHistory()])
898 core(item)->addRedirectURL(loader->clientRedirectDestinationForHistory());
901 if (!loader->serverRedirectSourceForHistory().isNull()) {
902 if (implementations) {
903 if (implementations->serverRedirectFunc) {
904 CallHistoryDelegate(implementations->serverRedirectFunc, view, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:),
905 loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_webFrame.get());
907 } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->serverRedirectSourceForHistory()])
908 core(item)->addRedirectURL(loader->serverRedirectDestinationForHistory());
912 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
914 WebView* view = getWebView(m_webFrame.get());
915 WebHistoryItem *webItem = kit(item);
917 return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
920 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
925 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
927 HistoryItem* historyItem = 0;
929 if (Page* page = core(m_webFrame.get())->page()) {
930 if (!page->settings()->privateBrowsingEnabled())
931 historyItem = page->backForward()->currentItem();
934 WebView *webView = getWebView(m_webFrame.get());
935 [webView _setGlobalHistoryItem:historyItem];
938 void WebFrameLoaderClient::didDisplayInsecureContent()
940 WebView *webView = getWebView(m_webFrame.get());
941 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
942 if (implementations->didDisplayInsecureContentFunc)
943 CallFrameLoadDelegate(implementations->didDisplayInsecureContentFunc, webView, @selector(webViewDidDisplayInsecureContent:));
946 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
948 WebView *webView = getWebView(m_webFrame.get());
949 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
950 if (implementations->didRunInsecureContentFunc) {
951 RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin]);
952 CallFrameLoadDelegate(implementations->didRunInsecureContentFunc, webView, @selector(webView:didRunInsecureContent:), webSecurityOrigin.get());
956 void WebFrameLoaderClient::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
958 WebView *webView = getWebView(m_webFrame.get());
959 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
960 if (implementations->didDetectXSSFunc) {
961 // FIXME: must pass didBlockEntirePage if we want to do more on mac than just pass tests.
962 NSURL* insecureNSURL = insecureURL;
963 CallFrameLoadDelegate(implementations->didDetectXSSFunc, webView, @selector(webView:didDetectXSS:), insecureNSURL);
967 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
969 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()];
972 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
974 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()];
977 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
979 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()];
982 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
984 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
987 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
989 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
992 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
994 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()];
997 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
999 NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
1000 contentURL:response.url()
1003 MIMEType:response.mimeType()];
1004 return [error autorelease];
1007 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1009 // FIXME: Needs to check domain.
1010 // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
1011 // loading plugin content twice. See <rdar://problem/4258008>
1012 return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
1015 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
1017 Frame* frame = core(m_webFrame.get());
1018 Page* page = frame->page();
1019 BOOL forMainFrame = page && page->mainFrame() == frame;
1020 return [WebView _canHandleRequest:request.nsURLRequest() forMainFrame:forMainFrame];
1023 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1025 return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType];
1028 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1030 return [WebView canShowMIMETypeAsHTML:MIMEType];
1033 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1035 return [WebView _representationExistsForURLScheme:URLScheme];
1038 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1040 return [WebView _generatedMIMETypeForURLScheme:URLScheme];
1043 void WebFrameLoaderClient::frameLoadCompleted()
1045 // Note: Can be called multiple times.
1047 // See WebFrameLoaderClient::provisionalLoadStarted.
1048 if ([getWebView(m_webFrame.get()) drawsBackground])
1049 [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:YES];
1052 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* item)
1057 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1059 // we might already be detached when this is called from detachFromParent, in which
1060 // case we don't want to override real data earlier gathered with (0,0)
1061 if ([docView superview] && [docView conformsToProtocol:@protocol(_WebDocumentViewState)])
1062 item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
1065 void WebFrameLoaderClient::restoreViewState()
1067 HistoryItem* currentItem = core(m_webFrame.get())->loader()->history()->currentItem();
1068 ASSERT(currentItem);
1070 // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
1071 // One counterexample is <rdar://problem/4917290>
1072 // For now, to cover this issue in release builds, there is no technical harm to returning
1073 // early and from a user standpoint - as in the above radar - the previous page load failed
1074 // so there *is* no scroll state to restore!
1078 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1079 if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
1080 id state = currentItem->viewState();
1082 [(id <_WebDocumentViewState>)docView setViewState:state];
1087 void WebFrameLoaderClient::provisionalLoadStarted()
1089 // Tell the scroll view not to draw a background so we can leave the contents of
1090 // the old page showing during the beginning of the loading process.
1092 // This will stay set to NO until:
1093 // 1) The load gets far enough along: WebFrameLoader::frameLoadCompleted.
1094 // 2) The window is resized: -[WebFrameView setFrameSize:].
1095 // or 3) The view is moved out of the window: -[WebFrameView viewDidMoveToWindow].
1096 // Please keep the comments in these four functions in agreement with each other.
1098 WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
1099 [scrollView setDrawsBackground:NO];
1100 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
1101 [scrollView setVerticalScrollElasticity:NSScrollElasticityNone];
1102 [scrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
1106 void WebFrameLoaderClient::didFinishLoad()
1108 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
1111 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1113 if (![m_webFrame.get() _dataSource]) {
1114 ASSERT(!core(m_webFrame.get())->tree()->childCount());
1118 // Make sure that any work that is triggered by resigning first reponder can get done.
1119 // The main example where this came up is the textDidEndEditing that is sent to the
1120 // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
1121 // remove the views as a side-effect of freeing the frame, at which point we can't
1122 // post the FormDelegate messages.
1124 // Note that this can also take FirstResponder away from a child of our frameView that
1125 // is not in a child frame's view. This is OK because we are in the process
1126 // of loading new content, which will blow away all editors in this top frame, and if
1127 // a non-editor is firstReponder it will not be affected by endEditingFor:.
1128 // Potentially one day someone could write a DocView whose editors were not all
1129 // replaced by loading new content, but that does not apply currently.
1130 NSView *frameView = m_webFrame->_private->webFrameView;
1131 NSWindow *window = [frameView window];
1132 NSResponder *firstResp = [window firstResponder];
1133 if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
1134 [window endEditingFor:firstResp];
1137 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1139 RefPtr<WebDocumentLoaderMac> loader = WebDocumentLoaderMac::create(request, substituteData);
1141 WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
1142 loader->setDataSource(dataSource, getWebView(m_webFrame.get()));
1143 [dataSource release];
1145 return loader.release();
1148 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1150 WebView* view = getWebView(m_webFrame.get());
1152 if ([view historyDelegate]) {
1153 WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
1154 if (!implementations->setTitleFunc)
1157 // FIXME: use direction of title.
1158 CallHistoryDelegate(implementations->setTitleFunc, view, @selector(webView:updateHistoryTitle:forURL:), (NSString *)title.string(), (NSString *)url);
1163 nsURL = [nsURL _webkit_canonicalize];
1166 NSString *titleNSString = title.string();
1168 [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
1171 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1173 OwnPtr<WebCachedFramePlatformData> webPlatformData = adoptPtr(new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]));
1174 cachedFrame->setCachedFramePlatformData(webPlatformData.release());
1177 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
1179 WebCachedFramePlatformData* platformData = reinterpret_cast<WebCachedFramePlatformData*>(cachedFrame->cachedFramePlatformData());
1180 NSView <WebDocumentView> *cachedView = platformData->webDocumentView();
1181 ASSERT(cachedView != nil);
1182 ASSERT(cachedFrame->documentLoader());
1183 [cachedView setDataSource:dataSource(cachedFrame->documentLoader())];
1185 // clean up webkit plugin instances before WebHTMLView gets freed.
1186 WebView *webView = getWebView(m_webFrame.get());
1187 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1189 [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
1192 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1194 WebView *webView = getWebView(m_webFrame.get());
1195 WebDataSource *dataSource = [m_webFrame.get() _dataSource];
1197 bool willProduceHTMLView = [m_webFrame->_private->webFrameView _viewClassForMIMEType:[dataSource _responseMIMEType]] == [WebHTMLView class];
1198 bool canSkipCreation = core(m_webFrame.get())->loader()->stateMachine()->committingFirstRealLoad() && willProduceHTMLView;
1199 if (canSkipCreation) {
1200 [[m_webFrame->_private->webFrameView documentView] setDataSource:dataSource];
1204 // Don't suppress scrollbars before the view creation if we're making the view for a non-HTML view.
1205 if (!willProduceHTMLView)
1206 [[m_webFrame->_private->webFrameView _scrollView] setScrollBarsSuppressed:NO repaintOnUnsuppress:NO];
1208 // clean up webkit plugin instances before WebHTMLView gets freed.
1209 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1211 NSView <WebDocumentView> *documentView = [m_webFrame->_private->webFrameView _makeDocumentViewForDataSource:dataSource];
1215 // FIXME: Could we skip some of this work for a top-level view that is not a WebHTMLView?
1217 // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
1218 Frame* coreFrame = core(m_webFrame.get());
1219 Page* page = coreFrame->page();
1220 bool isMainFrame = coreFrame == page->mainFrame();
1221 if (isMainFrame && coreFrame->view())
1222 coreFrame->view()->setParentVisible(false);
1223 coreFrame->setView(0);
1224 RefPtr<FrameView> coreView = FrameView::create(coreFrame);
1225 coreFrame->setView(coreView);
1227 [m_webFrame.get() _updateBackgroundAndUpdatesWhileOffscreen];
1228 [m_webFrame->_private->webFrameView _install];
1231 coreView->setParentVisible(true);
1233 // Call setDataSource on the document view after it has been placed in the view hierarchy.
1234 // This what we for the top-level view, so should do this for views in subframes as well.
1235 [documentView setDataSource:dataSource];
1237 // The following is a no-op for WebHTMLRepresentation, but for custom document types
1238 // like the ones that Safari uses for bookmarks it is the only way the DocumentLoader
1239 // will get the proper title.
1240 if (DocumentLoader* documentLoader = [dataSource _documentLoader])
1241 documentLoader->setTitle(StringWithDirection([dataSource pageTitle], LTR));
1243 if (HTMLFrameOwnerElement* owner = coreFrame->ownerElement())
1244 coreFrame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
1246 // If the document view implicitly became first responder, make sure to set the focused frame properly.
1247 if ([[documentView window] firstResponder] == documentView) {
1248 page->focusController()->setFocusedFrame(coreFrame);
1249 page->focusController()->setFocused(true);
1253 void WebFrameLoaderClient::didSaveToPageCache()
1257 void WebFrameLoaderClient::didRestoreFromPageCache()
1261 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1265 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
1267 // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1269 [m_policyListener.get() invalidate];
1271 WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
1272 m_policyListener = listener;
1274 m_policyFunction = function;
1279 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1281 ASSERT(m_policyListener);
1282 ASSERT(m_policyFunction);
1284 FramePolicyFunction function = m_policyFunction;
1286 m_policyListener = nil;
1287 m_policyFunction = 0;
1289 (core(m_webFrame.get())->loader()->policyChecker()->*function)(action);
1292 String WebFrameLoaderClient::userAgent(const KURL& url)
1294 WebView *webView = getWebView(m_webFrame.get());
1297 // We should never get here with nil for the WebView unless there is a bug somewhere else.
1298 // But if we do, it's better to return the empty string than just crashing on the spot.
1299 // Most other call sites are tolerant of nil because of Objective-C behavior, but this one
1300 // is not because the return value of _userAgentForURL is a const KURL&.
1304 return [webView _userAgentString];
1307 static const MouseEvent* findMouseEvent(const Event* event)
1309 for (const Event* e = event; e; e = e->underlyingEvent())
1310 if (e->isMouseEvent())
1311 return static_cast<const MouseEvent*>(e);
1315 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action, PassRefPtr<FormState> formState) const
1317 unsigned modifierFlags = 0;
1318 const Event* event = action.event();
1319 if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1320 if (keyStateEvent->ctrlKey())
1321 modifierFlags |= NSControlKeyMask;
1322 if (keyStateEvent->altKey())
1323 modifierFlags |= NSAlternateKeyMask;
1324 if (keyStateEvent->shiftKey())
1325 modifierFlags |= NSShiftKeyMask;
1326 if (keyStateEvent->metaKey())
1327 modifierFlags |= NSCommandKeyMask;
1330 NSURL *originalURL = action.url();
1332 NSMutableDictionary *result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
1333 [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1334 [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1335 originalURL, WebActionOriginalURLKey,
1338 if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1339 WebElementDictionary *element = [[WebElementDictionary alloc]
1340 initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)];
1341 [result setObject:element forKey:WebActionElementKey];
1344 [result setObject:[NSNumber numberWithInt:mouseEvent->button()] forKey:WebActionButtonKey];
1348 ASSERT(formState->form());
1349 [result setObject:kit(formState->form()) forKey:WebActionFormKey];
1355 bool WebFrameLoaderClient::canCachePage() const
1357 // We can only cache HTML pages right now
1358 return [[[m_webFrame.get() _dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1361 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1362 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1364 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1368 WebFrameView *childView = [[WebFrameView alloc] init];
1370 RefPtr<Frame> result = [WebFrame _createSubframeWithOwnerElement:ownerElement frameName:name frameView:childView];
1371 [childView release];
1373 WebFrame *newFrame = kit(result.get());
1375 if ([newFrame _dataSource])
1376 [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding());
1378 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1379 if (!result->page())
1382 core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, result.get());
1384 // The frame's onload handler may have removed it from the document.
1385 if (!result->tree()->parent())
1388 return result.release();
1390 END_BLOCK_OBJC_EXCEPTIONS;
1395 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1397 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1399 String type = mimeType;
1401 if (type.isEmpty()) {
1402 // Try to guess the MIME type based off the extension.
1404 NSString *extension = [[URL path] pathExtension];
1405 if ([extension length] > 0) {
1406 type = WKGetMIMETypeForExtension(extension);
1407 if (type.isEmpty()) {
1408 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
1409 if (WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForExtension:extension]) {
1410 if ([package isKindOfClass:[WebPluginPackage class]])
1411 return ObjectContentOtherPlugin;
1412 #if ENABLE(NETSCAPE_PLUGIN_API)
1414 ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
1415 return ObjectContentNetscapePlugin;
1424 return ObjectContentFrame; // Go ahead and hope that we can display the content.
1426 WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForMIMEType:type];
1427 ObjectContentType plugInType = ObjectContentNone;
1429 #if ENABLE(NETSCAPE_PLUGIN_API)
1430 if ([package isKindOfClass:[WebNetscapePluginPackage class]])
1431 plugInType = ObjectContentNetscapePlugin;
1435 ASSERT([package isKindOfClass:[WebPluginPackage class]]);
1436 plugInType = ObjectContentOtherPlugin;
1440 if (MIMETypeRegistry::isSupportedImageMIMEType(type))
1441 return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
1443 if (plugInType != ObjectContentNone)
1446 if ([m_webFrame->_private->webFrameView _viewClassForMIMEType:type])
1447 return ObjectContentFrame;
1449 return ObjectContentNone;
1451 END_BLOCK_OBJC_EXCEPTIONS;
1453 return ObjectContentNone;
1456 static NSMutableArray* kit(const Vector<String>& vector)
1458 unsigned len = vector.size();
1459 NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1460 for (unsigned x = 0; x < len; x++)
1461 [array addObject:vector[x]];
1465 static String parameterValue(const Vector<String>& paramNames, const Vector<String>& paramValues, const String& name)
1467 size_t size = paramNames.size();
1468 ASSERT(size == paramValues.size());
1469 for (size_t i = 0; i < size; ++i) {
1470 if (equalIgnoringCase(paramNames[i], name))
1471 return paramValues[i];
1476 static NSView *pluginView(WebFrame *frame, WebPluginPackage *pluginPackage,
1477 NSArray *attributeNames, NSArray *attributeValues, NSURL *baseURL,
1478 DOMElement *element, BOOL loadManually)
1480 WebHTMLView *docView = (WebHTMLView *)[[frame frameView] documentView];
1481 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1483 WebPluginController *pluginController = [docView _pluginController];
1485 // Store attributes in a dictionary so they can be passed to WebPlugins.
1486 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
1488 [pluginPackage load];
1489 Class viewFactory = [pluginPackage viewFactory];
1492 NSDictionary *arguments = nil;
1494 if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
1495 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1496 baseURL, WebPlugInBaseURLKey,
1497 attributes, WebPlugInAttributesKey,
1498 pluginController, WebPlugInContainerKey,
1499 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1500 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1501 element, WebPlugInContainingElementKey,
1503 LOG(Plugins, "arguments:\n%@", arguments);
1504 } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
1505 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1506 baseURL, WebPluginBaseURLKey,
1507 attributes, WebPluginAttributesKey,
1508 pluginController, WebPluginContainerKey,
1509 element, WebPlugInContainingElementKey,
1511 LOG(Plugins, "arguments:\n%@", arguments);
1514 view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
1515 [attributes release];
1519 class PluginWidget : public PluginViewBase {
1521 PluginWidget(NSView *view = 0)
1522 : PluginViewBase(view)
1527 virtual void invalidateRect(const IntRect& rect)
1529 [platformWidget() setNeedsDisplayInRect:rect];
1533 #if ENABLE(NETSCAPE_PLUGIN_API)
1535 class NetscapePluginWidget : public PluginWidget {
1537 NetscapePluginWidget(WebBaseNetscapePluginView *view)
1538 : PluginWidget(view)
1542 #if USE(ACCELERATED_COMPOSITING)
1543 virtual PlatformLayer* platformLayer() const
1545 return [(WebBaseNetscapePluginView *)platformWidget() pluginLayer];
1549 virtual bool getFormValue(String& value)
1551 NSString* nsValue = 0;
1552 if ([(WebBaseNetscapePluginView *)platformWidget() getFormValue:&nsValue]) {
1555 value = String(nsValue);
1562 virtual void handleEvent(Event* event)
1564 Frame* frame = Frame::frameForWidget(this);
1568 NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
1569 if (event->type() == eventNames().mousemoveEvent)
1570 [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
1571 else if (event->type() == eventNames().mouseoverEvent)
1572 [(WebBaseNetscapePluginView *)platformWidget() handleMouseEntered:currentNSEvent];
1573 else if (event->type() == eventNames().mouseoutEvent)
1574 [(WebBaseNetscapePluginView *)platformWidget() handleMouseExited:currentNSEvent];
1575 else if (event->type() == eventNames().contextmenuEvent)
1576 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.
1580 virtual void notifyWidget(WidgetNotification notification)
1582 switch (notification) {
1583 case WillPaintFlattened: {
1584 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1585 [(WebBaseNetscapePluginView *)platformWidget() cacheSnapshot];
1586 END_BLOCK_OBJC_EXCEPTIONS;
1589 case DidPaintFlattened: {
1590 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1591 [(WebBaseNetscapePluginView *)platformWidget() clearCachedSnapshot];
1592 END_BLOCK_OBJC_EXCEPTIONS;
1599 #if USE(PLUGIN_HOST_PROCESS)
1600 #define NETSCAPE_PLUGIN_VIEW WebHostedNetscapePluginView
1602 #define NETSCAPE_PLUGIN_VIEW WebNetscapePluginView
1605 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1607 static bool isOracleJavaPlugIn(NSString *bundleIdentifier)
1609 return [bundleIdentifier isEqualToString:@"com.oracle.java.JavaAppletPlugin"];
1612 static bool isPlugInInactive(NSString *bundleIdentifier)
1614 if (isOracleJavaPlugIn(bundleIdentifier) && !WKIsJavaPlugInActive())
1620 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& size, HTMLPlugInElement* element, const KURL& url,
1621 const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1623 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1625 ASSERT(paramNames.size() == paramValues.size());
1629 WebView *webView = getWebView(m_webFrame.get());
1630 SEL selector = @selector(webView:plugInViewWithArguments:);
1632 Document* document = core(m_webFrame.get())->document();
1633 NSURL *baseURL = document->baseURL();
1634 NSURL *pluginURL = url;
1636 // <rdar://problem/8366089>: AppleConnect has a bug where it does not
1637 // understand the parameter names specified in the <object> element that
1638 // embeds its plug-in. This site-specific hack works around the issue by
1639 // converting the parameter names to lowercase before passing them to the
1641 Frame* frame = core(m_webFrame.get());
1642 NSMutableArray *attributeKeys = kit(paramNames);
1643 if (frame && frame->settings()->needsSiteSpecificQuirks() && equalIgnoringCase(mimeType, "application/x-snkp")) {
1644 for (NSUInteger i = 0; i < [attributeKeys count]; ++i)
1645 [attributeKeys replaceObjectAtIndex:i withObject:[[attributeKeys objectAtIndex:i] lowercaseString]];
1648 if ([[webView UIDelegate] respondsToSelector:selector]) {
1649 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:attributeKeys];
1650 NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1651 attributes, WebPlugInAttributesKey,
1652 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1653 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1654 kit(element), WebPlugInContainingElementKey,
1655 // FIXME: We should be passing base URL, see <https://bugs.webkit.org/show_bug.cgi?id=35215>.
1656 pluginURL, WebPlugInBaseURLKey, // pluginURL might be nil, so add it last
1659 NSView *view = CallUIDelegate(webView, selector, arguments);
1661 [attributes release];
1662 [arguments release];
1665 return adoptRef(new PluginWidget(view));
1669 WebBasePluginPackage *pluginPackage;
1670 if (mimeType.isEmpty()) {
1672 pluginPackage = nil;
1674 MIMEType = mimeType;
1675 pluginPackage = [webView _pluginForMIMEType:mimeType];
1678 NSString *extension = [[pluginURL path] pathExtension];
1679 if (!pluginPackage && [extension length] && ![MIMEType length]) {
1680 pluginPackage = [webView _pluginForExtension:extension];
1681 if (pluginPackage) {
1682 NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
1683 if ([newMIMEType length] != 0)
1684 MIMEType = newMIMEType;
1690 if (pluginPackage) {
1691 if (WKShouldBlockPlugin([pluginPackage bundleIdentifier], [pluginPackage bundleVersion])) {
1692 errorCode = WebKitErrorBlockedPlugInVersion;
1693 if (element->renderer()->isEmbeddedObject())
1694 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
1695 } else if (isPlugInInactive([pluginPackage bundleIdentifier])) {
1696 if (element->renderer()->isEmbeddedObject())
1697 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginInactive);
1700 if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1701 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, attributeKeys, kit(paramValues), baseURL, kit(element), loadManually);
1703 #if ENABLE(NETSCAPE_PLUGIN_API)
1704 else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1705 WebBaseNetscapePluginView *pluginView = [[[NETSCAPE_PLUGIN_VIEW alloc]
1706 initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1707 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1711 attributeKeys:attributeKeys
1712 attributeValues:kit(paramValues)
1713 loadManually:loadManually
1714 element:element] autorelease];
1716 return adoptRef(new NetscapePluginWidget(pluginView));
1721 errorCode = WebKitErrorCannotFindPlugIn;
1723 if (!errorCode && !view)
1724 errorCode = WebKitErrorCannotLoadPlugIn;
1726 if (errorCode && m_webFrame) {
1727 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
1728 if (implementations->plugInFailedWithErrorFunc) {
1729 KURL pluginPageURL = document->completeURL(stripLeadingAndTrailingHTMLSpaces(parameterValue(paramNames, paramValues, "pluginspage")));
1730 if (!pluginPageURL.protocolIsInHTTPFamily())
1731 pluginPageURL = KURL();
1732 NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1734 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1735 contentURL:pluginURL pluginPageURL:pluginPageURL pluginName:pluginName MIMEType:MIMEType];
1736 CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1737 @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1745 return adoptRef(new PluginWidget(view));
1747 END_BLOCK_OBJC_EXCEPTIONS;
1752 void WebFrameLoaderClient::recreatePlugin(Widget*)
1756 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1761 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1763 WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[m_webFrame.get() _dataSource] representation];
1765 NSView *pluginView = pluginWidget->platformWidget();
1767 #if ENABLE(NETSCAPE_PLUGIN_API)
1768 if ([pluginView isKindOfClass:[NETSCAPE_PLUGIN_VIEW class]])
1769 [representation _redirectDataToManualLoader:(NETSCAPE_PLUGIN_VIEW *)pluginView forPluginView:pluginView];
1774 WebHTMLView *documentView = (WebHTMLView *)[[m_webFrame.get() frameView] documentView];
1775 ASSERT([documentView isKindOfClass:[WebHTMLView class]]);
1776 [representation _redirectDataToManualLoader:[documentView _pluginController] forPluginView:pluginView];
1779 END_BLOCK_OBJC_EXCEPTIONS;
1782 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const KURL& baseURL,
1783 const Vector<String>& paramNames, const Vector<String>& paramValues)
1785 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1789 NSString *MIMEType = @"application/x-java-applet";
1791 WebView *webView = getWebView(m_webFrame.get());
1793 WebBasePluginPackage *pluginPackage = [webView _pluginForMIMEType:MIMEType];
1795 int errorCode = WebKitErrorJavaUnavailable;
1797 if (pluginPackage) {
1798 if (WKShouldBlockPlugin([pluginPackage bundleIdentifier], [pluginPackage bundleVersion])) {
1799 errorCode = WebKitErrorBlockedPlugInVersion;
1800 if (element->renderer()->isEmbeddedObject())
1801 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
1802 } else if (isPlugInInactive([pluginPackage bundleIdentifier])) {
1803 if (element->renderer()->isEmbeddedObject())
1804 toRenderEmbeddedObject(element->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginInactive);
1807 #if ENABLE(NETSCAPE_PLUGIN_API)
1808 if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1809 view = [[[NETSCAPE_PLUGIN_VIEW alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1810 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1814 attributeKeys:kit(paramNames)
1815 attributeValues:kit(paramValues)
1817 element:element] autorelease];
1819 return adoptRef(new NetscapePluginWidget(static_cast<WebBaseNetscapePluginView *>(view)));
1826 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(getWebView(m_webFrame.get()));
1827 if (implementations->plugInFailedWithErrorFunc) {
1828 NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1829 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode contentURL:nil pluginPageURL:nil pluginName:pluginName MIMEType:MIMEType];
1830 CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1831 @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1836 END_BLOCK_OBJC_EXCEPTIONS;
1841 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1842 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize& size, HTMLMediaElement* element, const KURL& url,
1843 const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType)
1845 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1847 ASSERT(paramNames.size() == paramValues.size());
1851 WebView *webView = getWebView(m_webFrame.get());
1854 SEL selector = @selector(webView:plugInViewWithArguments:);
1856 if ([[webView UIDelegate] respondsToSelector:selector]) {
1857 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:kit(paramNames)];
1858 NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1859 attributes, WebPlugInAttributesKey,
1860 [NSNumber numberWithInt:WebPlugInModeEmbed], WebPlugInModeKey,
1861 [NSNumber numberWithBool:YES], WebPlugInShouldLoadMainResourceKey,
1862 kit(element), WebPlugInContainingElementKey,
1863 URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
1866 NSView *view = CallUIDelegate(webView, selector, arguments);
1868 [attributes release];
1869 [arguments release];
1872 return adoptRef(new PluginWidget(view));
1875 WebBasePluginPackage *pluginPackage = [webView _videoProxyPluginForMIMEType:mimeType];
1876 Document* document = core(m_webFrame.get())->document();
1877 NSURL *baseURL = document->baseURL();
1880 if (pluginPackage) {
1881 if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1882 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, kit(paramNames), kit(paramValues), baseURL, kit(element), false);
1884 errorCode = WebKitErrorCannotFindPlugIn;
1886 if (!errorCode && !view)
1887 errorCode = WebKitErrorCannotLoadPlugIn;
1890 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1891 contentURL:URL pluginPageURL:nil pluginName:[pluginPackage pluginInfo].name MIMEType:mimeType];
1892 WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1893 error:error DOMElement:kit(element)] autorelease];
1899 return adoptRef(new PluginWidget(view));
1901 END_BLOCK_OBJC_EXCEPTIONS;
1906 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget)
1908 [WebPluginController pluginViewHidden:widget->platformWidget()];
1911 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget)
1913 [WebPluginController addPlugInView:widget->platformWidget()];
1916 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1918 String WebFrameLoaderClient::overrideMediaType() const
1920 NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle];
1922 return overrideType;
1926 void WebFrameLoaderClient::documentElementAvailable() {
1929 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1931 WebView *webView = getWebView(m_webFrame.get());
1932 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1934 if (implementations->didClearWindowObjectForFrameInScriptWorldFunc) {
1935 CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameInScriptWorldFunc,
1936 webView, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:), m_webFrame.get(), [WebScriptWorld findOrCreateWorld:world]);
1940 if (world != mainThreadNormalWorld())
1943 Frame *frame = core(m_webFrame.get());
1944 ScriptController *script = frame->script();
1946 if (implementations->didClearWindowObjectForFrameFunc) {
1947 CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:),
1948 script->windowScriptObject(), m_webFrame.get());
1949 } else if (implementations->windowScriptObjectAvailableFunc) {
1950 CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:),
1951 script->windowScriptObject());
1954 if ([webView scriptDebugDelegate]) {
1955 [m_webFrame.get() _detachScriptDebugger];
1956 [m_webFrame.get() _attachScriptDebugger];
1960 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1962 #if ENABLE(ICONDATABASE)
1963 [[m_webFrame.get() webView] _registerForIconNotification:listen];
1967 void WebFrameLoaderClient::didPerformFirstNavigation() const
1969 WebPreferences *preferences = [[m_webFrame.get() webView] preferences];
1970 if ([preferences automaticallyDetectsCacheModel] && [preferences cacheModel] < WebCacheModelDocumentBrowser)
1971 [preferences setCacheModel:WebCacheModelDocumentBrowser];
1974 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1976 return WebFrameNetworkingContext::create(core(m_webFrame.get()));
1979 @implementation WebFramePolicyListener
1982 JSC::initializeThreading();
1983 WTF::initializeMainThreadToProcessMainThread();
1984 WebCore::RunLoop::initializeMainRunLoop();
1985 WebCoreObjCFinalizeOnMainThread(self);
1988 - (id)initWithWebCoreFrame:(Frame*)frame
2008 if (WebCoreObjCScheduleDeallocateOnMainThread([WebFramePolicyListener class], self))
2018 ASSERT_MAIN_THREAD();
2024 - (void)receivedPolicyDecision:(PolicyAction)action
2026 RefPtr<Frame> frame = adoptRef(m_frame);
2029 static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
2034 [self receivedPolicyDecision:PolicyIgnore];
2039 [self receivedPolicyDecision:PolicyDownload];
2044 [self receivedPolicyDecision:PolicyUse];
2049 [self receivedPolicyDecision:PolicyUse];