2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 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/MouseEvent.h>
108 #import <WebCore/Page.h>
109 #import <WebCore/PlatformString.h>
110 #import <WebCore/PluginViewBase.h>
111 #import <WebCore/ResourceError.h>
112 #import <WebCore/ResourceHandle.h>
113 #import <WebCore/ResourceLoader.h>
114 #import <WebCore/ResourceRequest.h>
115 #import <WebCore/ScriptController.h>
116 #import <WebCore/SharedBuffer.h>
117 #import <WebCore/WebCoreObjCExtras.h>
118 #import <WebCore/Widget.h>
119 #import <WebKit/DOMElement.h>
120 #import <WebKit/DOMHTMLFormElement.h>
121 #import <WebKitSystemInterface.h>
122 #import <runtime/InitializeThreading.h>
123 #import <wtf/MainThread.h>
124 #import <wtf/PassRefPtr.h>
126 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
127 #import <WebCore/HTMLMediaElement.h>
130 #if ENABLE(JAVA_BRIDGE)
131 #import "WebJavaPlugIn.h"
134 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
135 #import "NetscapePluginHostManager.h"
136 #import "WebHostedNetscapePluginView.h"
139 using namespace WebCore;
140 using namespace HTMLNames;
143 #if ENABLE(JAVA_BRIDGE)
144 @interface NSView (WebJavaPluginDetails)
145 - (jobject)pollForAppletInWindow:(NSWindow *)window;
149 @interface NSURLDownload (WebNSURLDownloadDetails)
150 - (void)_setOriginatingURL:(NSURL *)originatingURL;
153 // For backwards compatibility with older WebKit plug-ins.
154 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
155 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
156 NSString *WebPluginContainerKey = @"WebPluginContainer";
158 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> {
161 - (id)initWithWebCoreFrame:(Frame*)frame;
165 static inline WebDataSource *dataSource(DocumentLoader* loader)
167 return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
170 // Quirk for the Apple Dictionary application.
172 // If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,
173 // then for that frame's document, ignore changes to the scrolling attribute of frames. That script
174 // has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling
175 // attribute needs to be ignored to avoid showing extra scroll bars in the window.
176 // This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).
178 static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request)
180 if (!request.url().isLocalFile())
182 if (!request.url().string().endsWith("MainPageJavaScript.js"))
184 Frame* frame = core(client->webFrame());
187 if (frame->tree()->parent())
189 Document* document = frame->document();
192 HTMLHeadElement* head = document->head();
195 for (Node* c = head->firstChild(); c; c = c->nextSibling()) {
196 if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") {
197 document->setFrameElementsShouldIgnoreScrolling(true);
203 static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request)
205 // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in
206 // all applications other than Apple Dictionary.
207 static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"];
208 if (isAppleDictionary)
209 applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);
212 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
213 : m_webFrame(webFrame)
214 , m_policyFunction(0)
218 void WebFrameLoaderClient::frameLoaderDestroyed()
220 [m_webFrame.get() _clearCoreFrame];
224 bool WebFrameLoaderClient::hasWebView() const
226 return [m_webFrame.get() webView] != nil;
229 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
231 [dataSource(loader) _makeRepresentation];
234 bool WebFrameLoaderClient::hasHTMLView() const
236 if (![getWebView(m_webFrame.get()) _usesDocumentViews]) {
237 // FIXME (Viewless): For now we just assume that all frames have an HTML view
241 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
242 return [view isKindOfClass:[WebHTMLView class]];
245 void WebFrameLoaderClient::forceLayout()
247 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
248 [view setNeedsLayout:YES];
252 void WebFrameLoaderClient::forceLayoutForNonHTML()
254 WebFrameView *thisView = m_webFrame->_private->webFrameView;
255 if (!thisView) // Viewless mode.
257 NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
258 ASSERT(thisDocumentView != nil);
260 // Tell the just loaded document to layout. This may be necessary
261 // for non-html content that needs a layout message.
262 if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) {
263 [thisDocumentView setNeedsLayout:YES];
264 [thisDocumentView layout];
265 [thisDocumentView setNeedsDisplay:YES];
269 void WebFrameLoaderClient::setCopiesOnScroll()
271 [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
274 void WebFrameLoaderClient::detachedFromParent2()
276 //remove any NetScape plugins that are children of this frame because they are about to be detached
277 WebView *webView = getWebView(m_webFrame.get());
278 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
279 [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
282 void WebFrameLoaderClient::detachedFromParent3()
284 [m_webFrame->_private->webFrameView release];
285 m_webFrame->_private->webFrameView = nil;
288 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
291 ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
292 WebView *webView = getWebView(m_webFrame.get());
293 CFURLConnectionRef connection = handle->connection();
294 WebDownload *download = [WebDownload _downloadWithLoadingCFURLConnection:connection
295 request:request.cfURLRequest()
296 response:response.cfURLResponse()
297 delegate:[webView downloadDelegate]
299 setOriginalURLForDownload(download, initialRequest);
301 // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
302 handle->releaseConnectionForDownload();
303 CFRelease(connection);
305 id proxy = handle->releaseProxy();
308 WebView *webView = getWebView(m_webFrame.get());
309 WebDownload *download = [WebDownload _downloadWithLoadingConnection:handle->connection()
310 request:request.nsURLRequest()
311 response:response.nsURLResponse()
312 delegate:[webView downloadDelegate]
315 setOriginalURLForDownload(download, initialRequest);
319 void WebFrameLoaderClient::setOriginalURLForDownload(WebDownload *download, const ResourceRequest& initialRequest) const
321 NSURLRequest *initialURLRequest = initialRequest.nsURLRequest();
322 NSURL *originalURL = nil;
324 // If there was no referrer, don't traverse the back/forward history
325 // since this download was initiated directly. <rdar://problem/5294691>
326 if ([initialURLRequest valueForHTTPHeaderField:@"Referer"]) {
327 // find the first item in the history that was originated by the user
328 WebView *webView = getWebView(m_webFrame.get());
329 WebBackForwardList *history = [webView backForwardList];
330 int backListCount = [history backListCount];
331 for (int backIndex = 0; backIndex <= backListCount && !originalURL; backIndex++) {
332 // FIXME: At one point we had code here to check a "was user gesture" flag.
333 // Do we need to restore that logic?
334 originalURL = [[history itemAtIndex:-backIndex] URL];
339 originalURL = [initialURLRequest URL];
341 if ([download respondsToSelector:@selector(_setOriginatingURL:)]) {
342 NSString *scheme = [originalURL scheme];
343 NSString *host = [originalURL host];
344 if (scheme && host && [scheme length] && [host length]) {
345 NSNumber *port = [originalURL port];
346 if (port && [port intValue] < 0)
348 NSString *hostOnlyURLString;
350 hostOnlyURLString = [[NSString alloc] initWithFormat:@"%@://%@:%d", scheme, host, [port intValue]];
352 hostOnlyURLString = [[NSString alloc] initWithFormat:@"%@://%@", scheme, host];
353 NSURL *hostOnlyURL = [[NSURL alloc] initWithString:hostOnlyURLString];
354 [hostOnlyURLString release];
355 [download _setOriginatingURL:hostOnlyURL];
356 [hostOnlyURL release];
361 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
363 applyAppleDictionaryApplicationQuirk(this, request);
365 WebView *webView = getWebView(m_webFrame.get());
366 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
367 if (!implementations->didLoadResourceFromMemoryCacheFunc)
370 CallResourceLoadDelegate(implementations->didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
374 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
376 WebView *webView = getWebView(m_webFrame.get());
377 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
380 BOOL shouldRelease = NO;
381 if (implementations->identifierForRequestFunc)
382 object = CallResourceLoadDelegate(implementations->identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
384 object = [[NSObject alloc] init];
388 [webView _addObject:object forIdentifier:identifier];
394 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
396 applyAppleDictionaryApplicationQuirk(this, request);
398 WebView *webView = getWebView(m_webFrame.get());
399 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
401 if (redirectResponse.isNull())
402 static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
404 if (implementations->willSendRequestFunc)
405 request = (NSURLRequest *)CallResourceLoadDelegate(implementations->willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
408 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
410 WebView *webView = getWebView(m_webFrame.get());
411 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
413 if (implementations->shouldUseCredentialStorageFunc) {
414 if (id resource = [webView _objectForIdentifier:identifier])
415 return CallResourceLoadDelegateReturningBoolean(NO, implementations->shouldUseCredentialStorageFunc, webView, @selector(webView:resource:shouldUseCredentialStorageForDataSource:), resource, dataSource(loader));
421 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
423 WebView *webView = getWebView(m_webFrame.get());
424 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
426 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
428 if (implementations->didReceiveAuthenticationChallengeFunc) {
429 if (id resource = [webView _objectForIdentifier:identifier]) {
430 CallResourceLoadDelegate(implementations->didReceiveAuthenticationChallengeFunc, webView, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
435 NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
436 [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
439 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
440 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader* loader, unsigned long identifier, const ProtectionSpace& protectionSpace)
442 WebView *webView = getWebView(m_webFrame.get());
443 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
445 NSURLProtectionSpace *webProtectionSpace = mac(protectionSpace);
447 if (implementations->canAuthenticateAgainstProtectionSpaceFunc) {
448 if (id resource = [webView _objectForIdentifier:identifier]) {
449 return CallResourceLoadDelegateReturningBoolean(NO, implementations->canAuthenticateAgainstProtectionSpaceFunc, webView, @selector(webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:), resource, webProtectionSpace, dataSource(loader));
453 // If our resource load delegate doesn't handle the question, then only send authentication
454 // challenges for pre-10.6 protection spaces. This is the same as the default implementation
456 return (protectionSpace.authenticationScheme() < ProtectionSpaceAuthenticationSchemeClientCertificateRequested);
460 bool WebFrameLoaderClient::shouldPaintBrokenImage(const KURL& imageURL) const
462 WebView *webView = getWebView(m_webFrame.get());
463 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
465 if (implementations->shouldPaintBrokenImageForURLFunc) {
466 NSURL* url = imageURL;
467 return CallResourceLoadDelegateReturningBoolean(YES, implementations->shouldPaintBrokenImageForURLFunc, webView, @selector(webView:shouldPaintBrokenImageForURL:), url);
472 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
474 WebView *webView = getWebView(m_webFrame.get());
475 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
476 NSURLAuthenticationChallenge *webChallenge = mac(challenge);
478 if (implementations->didCancelAuthenticationChallengeFunc) {
479 if (id resource = [webView _objectForIdentifier:identifier]) {
480 CallResourceLoadDelegate(implementations->didCancelAuthenticationChallengeFunc, webView, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
485 [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
488 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
490 WebView *webView = getWebView(m_webFrame.get());
491 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
492 if (implementations->didReceiveResponseFunc) {
493 if (id resource = [webView _objectForIdentifier:identifier])
494 CallResourceLoadDelegate(implementations->didReceiveResponseFunc, webView, @selector(webView:resource:didReceiveResponse:fromDataSource:), resource, response.nsURLResponse(), dataSource(loader));
498 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loader, unsigned long identifier, NSCachedURLResponse* response) const
500 WebView *webView = getWebView(m_webFrame.get());
501 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
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));
511 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int dataLength)
513 WebView *webView = getWebView(m_webFrame.get());
514 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
515 if (implementations->didReceiveContentLengthFunc) {
516 if (id resource = [webView _objectForIdentifier:identifier])
517 CallResourceLoadDelegate(implementations->didReceiveContentLengthFunc, webView, @selector(webView:resource:didReceiveContentLength:fromDataSource:), resource, (NSInteger)dataLength, dataSource(loader));
521 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
523 WebView *webView = getWebView(m_webFrame.get());
524 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
526 if (implementations->didFinishLoadingFromDataSourceFunc) {
527 if (id resource = [webView _objectForIdentifier:identifier])
528 CallResourceLoadDelegate(implementations->didFinishLoadingFromDataSourceFunc, webView, @selector(webView:resource:didFinishLoadingFromDataSource:), resource, dataSource(loader));
531 [webView _removeObjectForIdentifier:identifier];
533 static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
536 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
538 WebView *webView = getWebView(m_webFrame.get());
539 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
541 if (implementations->didFailLoadingWithErrorFromDataSourceFunc) {
542 if (id resource = [webView _objectForIdentifier:identifier])
543 CallResourceLoadDelegate(implementations->didFailLoadingWithErrorFromDataSourceFunc, webView, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), resource, (NSError *)error, dataSource(loader));
546 [webView _removeObjectForIdentifier:identifier];
548 static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
551 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
553 WebView *webView = getWebView(m_webFrame.get());
554 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
555 if (implementations->didHandleOnloadEventsForFrameFunc)
556 CallFrameLoadDelegate(implementations->didHandleOnloadEventsForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
559 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
561 WebView *webView = getWebView(m_webFrame.get());
562 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
563 if (implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc)
564 CallFrameLoadDelegate(implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc, webView, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:), m_webFrame.get());
567 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
569 WebView *webView = getWebView(m_webFrame.get());
570 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
571 if (implementations->didCancelClientRedirectForFrameFunc)
572 CallFrameLoadDelegate(implementations->didCancelClientRedirectForFrameFunc, webView, @selector(webView:didCancelClientRedirectForFrame:), m_webFrame.get());
575 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
577 WebView *webView = getWebView(m_webFrame.get());
578 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
579 if (implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc) {
580 NSURL *cocoaURL = url;
581 CallFrameLoadDelegate(implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc, webView, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), cocoaURL, delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
585 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
587 WebView *webView = getWebView(m_webFrame.get());
588 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
589 if (implementations->didChangeLocationWithinPageForFrameFunc)
590 CallFrameLoadDelegate(implementations->didChangeLocationWithinPageForFrameFunc, webView, @selector(webView:didChangeLocationWithinPageForFrame:), m_webFrame.get());
593 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
595 WebView *webView = getWebView(m_webFrame.get());
596 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
597 if (implementations->didPushStateWithinPageForFrameFunc)
598 CallFrameLoadDelegate(implementations->didPushStateWithinPageForFrameFunc, webView, @selector(webView:didPushStateWithinPageForFrame:), m_webFrame.get());
601 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
603 WebView *webView = getWebView(m_webFrame.get());
604 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
605 if (implementations->didReplaceStateWithinPageForFrameFunc)
606 CallFrameLoadDelegate(implementations->didReplaceStateWithinPageForFrameFunc, webView, @selector(webView:didReplaceStateWithinPageForFrame:), m_webFrame.get());
609 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
611 WebView *webView = getWebView(m_webFrame.get());
612 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
613 if (implementations->didPopStateWithinPageForFrameFunc)
614 CallFrameLoadDelegate(implementations->didPopStateWithinPageForFrameFunc, webView, @selector(webView:didPopStateWithinPageForFrame:), m_webFrame.get());
617 void WebFrameLoaderClient::dispatchWillClose()
619 WebView *webView = getWebView(m_webFrame.get());
620 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
621 if (implementations->willCloseFrameFunc)
622 CallFrameLoadDelegate(implementations->willCloseFrameFunc, webView, @selector(webView:willCloseFrame:), m_webFrame.get());
625 void WebFrameLoaderClient::dispatchDidReceiveIcon()
627 #if ENABLE(ICONDATABASE)
628 WebView *webView = getWebView(m_webFrame.get());
629 ASSERT(m_webFrame == [webView mainFrame]);
630 [webView _dispatchDidReceiveIconFromWebFrame:m_webFrame.get()];
634 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
636 WebView *webView = getWebView(m_webFrame.get());
637 [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
639 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
640 if (implementations->didStartProvisionalLoadForFrameFunc)
641 CallFrameLoadDelegate(implementations->didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
644 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
646 WebView *webView = getWebView(m_webFrame.get());
647 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
648 if (implementations->didReceiveTitleForFrameFunc)
649 // FIXME: use direction of title.
650 CallFrameLoadDelegate(implementations->didReceiveTitleForFrameFunc, webView, @selector(webView:didReceiveTitle:forFrame:), (NSString *)title.string(), m_webFrame.get());
653 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
655 // FIXME: Implement this to allow container to update favicon.
658 void WebFrameLoaderClient::dispatchDidCommitLoad()
660 // Tell the client we've committed this URL.
661 ASSERT([m_webFrame->_private->webFrameView documentView] != nil || ![getWebView(m_webFrame.get()) _usesDocumentViews]);
663 WebView *webView = getWebView(m_webFrame.get());
664 [webView _didCommitLoadForFrame:m_webFrame.get()];
666 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
667 if (implementations->didCommitLoadForFrameFunc)
668 CallFrameLoadDelegate(implementations->didCommitLoadForFrameFunc, webView, @selector(webView:didCommitLoadForFrame:), m_webFrame.get());
671 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
673 WebView *webView = getWebView(m_webFrame.get());
674 [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
676 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
677 if (implementations->didFailProvisionalLoadWithErrorForFrameFunc)
678 CallFrameLoadDelegate(implementations->didFailProvisionalLoadWithErrorForFrameFunc, webView, @selector(webView:didFailProvisionalLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
680 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
683 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
685 WebView *webView = getWebView(m_webFrame.get());
686 [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
688 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
689 if (implementations->didFailLoadWithErrorForFrameFunc)
690 CallFrameLoadDelegate(implementations->didFailLoadWithErrorForFrameFunc, webView, @selector(webView:didFailLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
692 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
695 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
697 WebView *webView = getWebView(m_webFrame.get());
698 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
699 if (implementations->didFinishDocumentLoadForFrameFunc)
700 CallFrameLoadDelegate(implementations->didFinishDocumentLoadForFrameFunc, webView, @selector(webView:didFinishDocumentLoadForFrame:), m_webFrame.get());
703 void WebFrameLoaderClient::dispatchDidFinishLoad()
705 WebView *webView = getWebView(m_webFrame.get());
706 [webView _didFinishLoadForFrame:m_webFrame.get()];
708 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
709 if (implementations->didFinishLoadForFrameFunc)
710 CallFrameLoadDelegate(implementations->didFinishLoadForFrameFunc, webView, @selector(webView:didFinishLoadForFrame:), m_webFrame.get());
712 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
715 void WebFrameLoaderClient::dispatchDidFirstLayout()
717 WebView *webView = getWebView(m_webFrame.get());
718 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
719 if (implementations->didFirstLayoutInFrameFunc)
720 CallFrameLoadDelegate(implementations->didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
722 // See WebFrameLoaderClient::provisionalLoadStarted.
723 WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
724 if ([getWebView(m_webFrame.get()) drawsBackground])
725 [scrollView setDrawsBackground:YES];
726 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
727 [scrollView setVerticalScrollElasticity:NSScrollElasticityAutomatic];
728 [scrollView setHorizontalScrollElasticity:NSScrollElasticityAutomatic];
732 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
734 WebView *webView = getWebView(m_webFrame.get());
735 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
736 if (implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc)
737 CallFrameLoadDelegate(implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc, webView, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:), m_webFrame.get());
740 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
742 WebView *currentWebView = getWebView(m_webFrame.get());
743 NSDictionary *features = [[NSDictionary alloc] init];
744 WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView
745 createWebViewWithRequest:nil
746 windowFeatures:features];
749 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
751 WebKit::NetscapePluginHostManager::shared().didCreateWindow();
754 return core([newWebView mainFrame]);
757 void WebFrameLoaderClient::dispatchShow()
759 WebView *webView = getWebView(m_webFrame.get());
760 [[webView _UIDelegateForwarder] webViewShow:webView];
763 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function,
764 const ResourceResponse& response, const ResourceRequest& request)
766 WebView *webView = getWebView(m_webFrame.get());
768 [[webView _policyDelegateForwarder] webView:webView
769 decidePolicyForMIMEType:response.mimeType()
770 request:request.nsURLRequest()
771 frame:m_webFrame.get()
772 decisionListener:setUpPolicyListener(function).get()];
775 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
776 const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
778 WebView *webView = getWebView(m_webFrame.get());
779 [[webView _policyDelegateForwarder] webView:webView
780 decidePolicyForNewWindowAction:actionDictionary(action, formState)
781 request:request.nsURLRequest()
782 newFrameName:frameName
783 decisionListener:setUpPolicyListener(function).get()];
786 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
787 const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
789 WebView *webView = getWebView(m_webFrame.get());
790 [[webView _policyDelegateForwarder] webView:webView
791 decidePolicyForNavigationAction:actionDictionary(action, formState)
792 request:request.nsURLRequest()
793 frame:m_webFrame.get()
794 decisionListener:setUpPolicyListener(function).get()];
797 void WebFrameLoaderClient::cancelPolicyCheck()
799 [m_policyListener.get() invalidate];
800 m_policyListener = nil;
801 m_policyFunction = 0;
804 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
806 WebView *webView = getWebView(m_webFrame.get());
807 [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];
810 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
812 id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
814 (core(m_webFrame.get())->loader()->policyChecker()->*function)(PolicyUse);
818 const StringPairVector& textFieldValues = formState->textFieldValues();
819 size_t size = textFieldValues.size();
820 NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:size];
821 for (size_t i = 0; i < size; ++i)
822 [dictionary setObject:textFieldValues[i].second forKey:textFieldValues[i].first];
824 CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceFrame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
826 [dictionary release];
829 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
833 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
835 [dataSource(loader) _revertToProvisionalState];
838 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
840 [dataSource(loader) _setMainDocumentError:error];
843 void WebFrameLoaderClient::willChangeEstimatedProgress()
845 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
848 void WebFrameLoaderClient::didChangeEstimatedProgress()
850 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
853 void WebFrameLoaderClient::postProgressStartedNotification()
855 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
858 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
860 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
863 void WebFrameLoaderClient::postProgressFinishedNotification()
865 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
868 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
870 [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
873 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
875 // FIXME: Should download full request.
876 WebDownload *download = [getWebView(m_webFrame.get()) _downloadURL:request.url()];
878 setOriginalURLForDownload(download, request);
881 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
883 // FIXME: Should do this only in main frame case, right?
884 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
887 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
889 // FIXME: Should do this only in main frame case, right?
890 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
893 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
895 NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
896 [dataSource(loader) _receivedData:nsData];
900 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
902 [dataSource(loader) _finishedLoading];
905 void WebFrameLoaderClient::updateGlobalHistory()
907 WebView* view = getWebView(m_webFrame.get());
908 DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
910 if ([view historyDelegate]) {
911 WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
912 if (implementations->navigatedFunc) {
913 WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->urlForHistory()
914 title:loader->title().string()
915 originalRequest:loader->originalRequestCopy().nsURLRequest()
916 response:loader->response().nsURLResponse()
917 hasSubstituteData:loader->substituteData().isValid()
918 clientRedirectSource:loader->clientRedirectSourceForHistory()];
920 CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
927 [[WebHistory optionalSharedHistory] _visitedURL:loader->urlForHistory()
928 withTitle:loader->title().string()
929 method:loader->originalRequestCopy().httpMethod()
930 wasFailure:loader->urlForHistoryReflectsFailure()
931 increaseVisitCount:!loader->clientRedirectSourceForHistory()]; // Do not increase visit count due to navigations that were not initiated by the user directly, avoiding growth from programmatic reloads.
934 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
936 WebView* view = getWebView(m_webFrame.get());
937 WebHistoryDelegateImplementationCache* implementations = [view historyDelegate] ? WebViewGetHistoryDelegateImplementations(view) : 0;
939 DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
940 ASSERT(loader->unreachableURL().isEmpty());
942 if (!loader->clientRedirectSourceForHistory().isNull()) {
943 if (implementations) {
944 if (implementations->clientRedirectFunc) {
945 CallHistoryDelegate(implementations->clientRedirectFunc, view, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:),
946 loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_webFrame.get());
948 } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->clientRedirectSourceForHistory()])
949 core(item)->addRedirectURL(loader->clientRedirectDestinationForHistory());
952 if (!loader->serverRedirectSourceForHistory().isNull()) {
953 if (implementations) {
954 if (implementations->serverRedirectFunc) {
955 CallHistoryDelegate(implementations->serverRedirectFunc, view, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:),
956 loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_webFrame.get());
958 } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->serverRedirectSourceForHistory()])
959 core(item)->addRedirectURL(loader->serverRedirectDestinationForHistory());
963 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
965 WebView* view = getWebView(m_webFrame.get());
966 WebHistoryItem *webItem = kit(item);
968 return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
971 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
976 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
980 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
984 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
988 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
990 HistoryItem* historyItem = 0;
992 if (Page* page = core(m_webFrame.get())->page()) {
993 if (!page->settings()->privateBrowsingEnabled())
994 historyItem = page->backForward()->currentItem();
997 WebView *webView = getWebView(m_webFrame.get());
998 [webView _setGlobalHistoryItem:historyItem];
1001 void WebFrameLoaderClient::didDisplayInsecureContent()
1003 WebView *webView = getWebView(m_webFrame.get());
1004 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1005 if (implementations->didDisplayInsecureContentFunc)
1006 CallFrameLoadDelegate(implementations->didDisplayInsecureContentFunc, webView, @selector(webViewDidDisplayInsecureContent:));
1009 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
1011 RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin]);
1013 WebView *webView = getWebView(m_webFrame.get());
1014 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1015 if (implementations->didRunInsecureContentFunc)
1016 CallFrameLoadDelegate(implementations->didRunInsecureContentFunc, webView, @selector(webView:didRunInsecureContent:), webSecurityOrigin.get());
1019 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
1021 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()];
1024 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
1026 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()];
1029 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
1031 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()];
1034 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1036 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
1039 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1041 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
1044 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1046 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()];
1049 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1051 NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
1052 contentURL:response.url()
1055 MIMEType:response.mimeType()];
1056 return [error autorelease];
1059 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1061 // FIXME: Needs to check domain.
1062 // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
1063 // loading plugin content twice. See <rdar://problem/4258008>
1064 return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
1067 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
1069 Frame* frame = core(m_webFrame.get());
1070 Page* page = frame->page();
1071 BOOL forMainFrame = page && page->mainFrame() == frame;
1072 return [WebView _canHandleRequest:request.nsURLRequest() forMainFrame:forMainFrame];
1075 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1077 return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType];
1080 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1082 return [WebView canShowMIMETypeAsHTML:MIMEType];
1085 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1087 return [WebView _representationExistsForURLScheme:URLScheme];
1090 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1092 return [WebView _generatedMIMETypeForURLScheme:URLScheme];
1095 void WebFrameLoaderClient::frameLoadCompleted()
1097 // Note: Can be called multiple times.
1099 // See WebFrameLoaderClient::provisionalLoadStarted.
1100 if ([getWebView(m_webFrame.get()) drawsBackground])
1101 [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:YES];
1104 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* item)
1109 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1111 // we might already be detached when this is called from detachFromParent, in which
1112 // case we don't want to override real data earlier gathered with (0,0)
1113 if ([docView superview] && [docView conformsToProtocol:@protocol(_WebDocumentViewState)])
1114 item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
1117 void WebFrameLoaderClient::restoreViewState()
1119 HistoryItem* currentItem = core(m_webFrame.get())->loader()->history()->currentItem();
1120 ASSERT(currentItem);
1122 // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
1123 // One counterexample is <rdar://problem/4917290>
1124 // For now, to cover this issue in release builds, there is no technical harm to returning
1125 // early and from a user standpoint - as in the above radar - the previous page load failed
1126 // so there *is* no scroll state to restore!
1130 NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
1131 if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
1132 id state = currentItem->viewState();
1134 [(id <_WebDocumentViewState>)docView setViewState:state];
1139 void WebFrameLoaderClient::provisionalLoadStarted()
1141 // Tell the scroll view not to draw a background so we can leave the contents of
1142 // the old page showing during the beginning of the loading process.
1144 // This will stay set to NO until:
1145 // 1) The load gets far enough along: WebFrameLoader::frameLoadCompleted.
1146 // 2) The window is resized: -[WebFrameView setFrameSize:].
1147 // or 3) The view is moved out of the window: -[WebFrameView viewDidMoveToWindow].
1148 // Please keep the comments in these four functions in agreement with each other.
1150 WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
1151 [scrollView setDrawsBackground:NO];
1152 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
1153 [scrollView setVerticalScrollElasticity:NSScrollElasticityNone];
1154 [scrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
1158 void WebFrameLoaderClient::didFinishLoad()
1160 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
1163 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1165 if (![m_webFrame.get() _dataSource]) {
1166 ASSERT(!core(m_webFrame.get())->tree()->childCount());
1170 // Make sure that any work that is triggered by resigning first reponder can get done.
1171 // The main example where this came up is the textDidEndEditing that is sent to the
1172 // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
1173 // remove the views as a side-effect of freeing the frame, at which point we can't
1174 // post the FormDelegate messages.
1176 // Note that this can also take FirstResponder away from a child of our frameView that
1177 // is not in a child frame's view. This is OK because we are in the process
1178 // of loading new content, which will blow away all editors in this top frame, and if
1179 // a non-editor is firstReponder it will not be affected by endEditingFor:.
1180 // Potentially one day someone could write a DocView whose editors were not all
1181 // replaced by loading new content, but that does not apply currently.
1182 NSView *frameView = m_webFrame->_private->webFrameView;
1183 NSWindow *window = [frameView window];
1184 NSResponder *firstResp = [window firstResponder];
1185 if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
1186 [window endEditingFor:firstResp];
1189 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1191 RefPtr<WebDocumentLoaderMac> loader = WebDocumentLoaderMac::create(request, substituteData);
1193 WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
1194 loader->setDataSource(dataSource, getWebView(m_webFrame.get()));
1195 [dataSource release];
1197 return loader.release();
1200 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1202 WebView* view = getWebView(m_webFrame.get());
1204 if ([view historyDelegate]) {
1205 WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
1206 if (!implementations->setTitleFunc)
1209 // FIXME: use direction of title.
1210 CallHistoryDelegate(implementations->setTitleFunc, view, @selector(webView:updateHistoryTitle:forURL:), (NSString *)title.string(), (NSString *)url);
1215 nsURL = [nsURL _webkit_canonicalize];
1218 NSString *titleNSString = title.string();
1220 [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
1223 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1225 OwnPtr<WebCachedFramePlatformData> webPlatformData = adoptPtr(new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]));
1226 cachedFrame->setCachedFramePlatformData(webPlatformData.release());
1229 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
1231 WebCachedFramePlatformData* platformData = reinterpret_cast<WebCachedFramePlatformData*>(cachedFrame->cachedFramePlatformData());
1232 NSView <WebDocumentView> *cachedView = platformData->webDocumentView();
1233 ASSERT(cachedView != nil);
1234 ASSERT(cachedFrame->documentLoader());
1235 [cachedView setDataSource:dataSource(cachedFrame->documentLoader())];
1237 // clean up webkit plugin instances before WebHTMLView gets freed.
1238 WebView *webView = getWebView(m_webFrame.get());
1239 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1241 [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
1244 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1246 WebView *webView = getWebView(m_webFrame.get());
1247 WebDataSource *dataSource = [m_webFrame.get() _dataSource];
1248 bool usesDocumentViews = [webView _usesDocumentViews];
1250 if (usesDocumentViews) {
1251 // FIXME (Viewless): I assume we want the equivalent of this optimization for viewless mode too.
1252 bool willProduceHTMLView = [m_webFrame->_private->webFrameView _viewClassForMIMEType:[dataSource _responseMIMEType]] == [WebHTMLView class];
1253 bool canSkipCreation = core(m_webFrame.get())->loader()->stateMachine()->committingFirstRealLoad() && willProduceHTMLView;
1254 if (canSkipCreation) {
1255 [[m_webFrame->_private->webFrameView documentView] setDataSource:dataSource];
1259 // Don't suppress scrollbars before the view creation if we're making the view for a non-HTML view.
1260 if (!willProduceHTMLView)
1261 [[m_webFrame->_private->webFrameView _scrollView] setScrollBarsSuppressed:NO repaintOnUnsuppress:NO];
1264 // clean up webkit plugin instances before WebHTMLView gets freed.
1265 [webView removePluginInstanceViewsFor:(m_webFrame.get())];
1267 NSView <WebDocumentView> *documentView = nil;
1268 if (usesDocumentViews) {
1269 documentView = [m_webFrame->_private->webFrameView _makeDocumentViewForDataSource:dataSource];
1274 // FIXME: Could we skip some of this work for a top-level view that is not a WebHTMLView?
1276 // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
1277 Frame* coreFrame = core(m_webFrame.get());
1278 Page* page = coreFrame->page();
1279 bool isMainFrame = coreFrame == page->mainFrame();
1280 if (isMainFrame && coreFrame->view())
1281 coreFrame->view()->setParentVisible(false);
1282 coreFrame->setView(0);
1283 RefPtr<FrameView> coreView;
1284 if (usesDocumentViews)
1285 coreView = FrameView::create(coreFrame);
1287 coreView = FrameView::create(coreFrame, IntSize([webView bounds].size));
1288 coreFrame->setView(coreView);
1290 [m_webFrame.get() _updateBackgroundAndUpdatesWhileOffscreen];
1292 if (usesDocumentViews)
1293 [m_webFrame->_private->webFrameView _install];
1296 coreView->setParentVisible(true);
1298 if (usesDocumentViews) {
1299 // Call setDataSource on the document view after it has been placed in the view hierarchy.
1300 // This what we for the top-level view, so should do this for views in subframes as well.
1301 [documentView setDataSource:dataSource];
1303 // The following is a no-op for WebHTMLRepresentation, but for custom document types
1304 // like the ones that Safari uses for bookmarks it is the only way the DocumentLoader
1305 // will get the proper title.
1306 if (DocumentLoader* documentLoader = [dataSource _documentLoader])
1307 documentLoader->setTitle(StringWithDirection([dataSource pageTitle], LTR));
1310 if (HTMLFrameOwnerElement* owner = coreFrame->ownerElement())
1311 coreFrame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
1313 // If the document view implicitly became first responder, make sure to set the focused frame properly.
1314 if (usesDocumentViews && [[documentView window] firstResponder] == documentView) {
1315 page->focusController()->setFocusedFrame(coreFrame);
1316 page->focusController()->setFocused(true);
1320 void WebFrameLoaderClient::didSaveToPageCache()
1324 void WebFrameLoaderClient::didRestoreFromPageCache()
1328 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1332 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
1334 // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1336 [m_policyListener.get() invalidate];
1338 WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
1339 m_policyListener = listener;
1341 m_policyFunction = function;
1346 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
1348 ASSERT(m_policyListener);
1349 ASSERT(m_policyFunction);
1351 FramePolicyFunction function = m_policyFunction;
1353 m_policyListener = nil;
1354 m_policyFunction = 0;
1356 (core(m_webFrame.get())->loader()->policyChecker()->*function)(action);
1359 String WebFrameLoaderClient::userAgent(const KURL& url)
1361 WebView *webView = getWebView(m_webFrame.get());
1364 // We should never get here with nil for the WebView unless there is a bug somewhere else.
1365 // But if we do, it's better to return the empty string than just crashing on the spot.
1366 // Most other call sites are tolerant of nil because of Objective-C behavior, but this one
1367 // is not because the return value of _userAgentForURL is a const KURL&.
1371 return [webView userAgentForURL:url];
1374 static const MouseEvent* findMouseEvent(const Event* event)
1376 for (const Event* e = event; e; e = e->underlyingEvent())
1377 if (e->isMouseEvent())
1378 return static_cast<const MouseEvent*>(e);
1382 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action, PassRefPtr<FormState> formState) const
1384 unsigned modifierFlags = 0;
1385 const Event* event = action.event();
1386 if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
1387 if (keyStateEvent->ctrlKey())
1388 modifierFlags |= NSControlKeyMask;
1389 if (keyStateEvent->altKey())
1390 modifierFlags |= NSAlternateKeyMask;
1391 if (keyStateEvent->shiftKey())
1392 modifierFlags |= NSShiftKeyMask;
1393 if (keyStateEvent->metaKey())
1394 modifierFlags |= NSCommandKeyMask;
1397 NSURL *originalURL = action.url();
1399 NSMutableDictionary *result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
1400 [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
1401 [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
1402 originalURL, WebActionOriginalURLKey,
1405 if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
1406 WebElementDictionary *element = [[WebElementDictionary alloc]
1407 initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)];
1408 [result setObject:element forKey:WebActionElementKey];
1411 [result setObject:[NSNumber numberWithInt:mouseEvent->button()] forKey:WebActionButtonKey];
1415 ASSERT(formState->form());
1416 [result setObject:kit(formState->form()) forKey:WebActionFormKey];
1422 bool WebFrameLoaderClient::canCachePage() const
1424 // We can only cache HTML pages right now
1425 return [[[m_webFrame.get() _dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
1428 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1429 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1431 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1435 WebFrameView *childView = [getWebView(m_webFrame.get()) _usesDocumentViews] ? [[WebFrameView alloc] init] : nil;
1437 RefPtr<Frame> result = [WebFrame _createSubframeWithOwnerElement:ownerElement frameName:name frameView:childView];
1438 [childView release];
1440 WebFrame *newFrame = kit(result.get());
1442 if ([newFrame _dataSource])
1443 [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding());
1445 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1446 if (!result->page())
1449 core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, result.get());
1451 // The frame's onload handler may have removed it from the document.
1452 if (!result->tree()->parent())
1455 return result.release();
1457 END_BLOCK_OBJC_EXCEPTIONS;
1462 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page* oldPage)
1466 void WebFrameLoaderClient::transferLoadingResourceFromPage(ResourceLoader* loader, const ResourceRequest& originalRequest, Page* oldPage)
1468 ASSERT(oldPage != core(m_webFrame.get())->page());
1470 unsigned long identifier = loader->identifier();
1471 ASSERT(![getWebView(m_webFrame.get()) _objectForIdentifier:identifier]);
1473 assignIdentifierToInitialRequest(identifier, loader->documentLoader(), originalRequest);
1475 [kit(oldPage) _removeObjectForIdentifier:identifier];
1478 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1480 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1482 String type = mimeType;
1484 if (type.isEmpty()) {
1485 // Try to guess the MIME type based off the extension.
1487 NSString *extension = [[URL path] pathExtension];
1488 if ([extension length] > 0) {
1489 type = WKGetMIMETypeForExtension(extension);
1490 if (type.isEmpty()) {
1491 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
1492 if (WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForExtension:extension]) {
1493 if ([package isKindOfClass:[WebPluginPackage class]])
1494 return ObjectContentOtherPlugin;
1495 #if ENABLE(NETSCAPE_PLUGIN_API)
1497 ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
1498 return ObjectContentNetscapePlugin;
1507 return ObjectContentFrame; // Go ahead and hope that we can display the content.
1509 WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForMIMEType:type];
1510 ObjectContentType plugInType = ObjectContentNone;
1512 #if ENABLE(NETSCAPE_PLUGIN_API)
1513 if ([package isKindOfClass:[WebNetscapePluginPackage class]])
1514 plugInType = ObjectContentNetscapePlugin;
1518 ASSERT([package isKindOfClass:[WebPluginPackage class]]);
1519 plugInType = ObjectContentOtherPlugin;
1523 if (MIMETypeRegistry::isSupportedImageMIMEType(type))
1524 return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
1526 if (plugInType != ObjectContentNone)
1529 if ([m_webFrame->_private->webFrameView _viewClassForMIMEType:type])
1530 return ObjectContentFrame;
1532 return ObjectContentNone;
1534 END_BLOCK_OBJC_EXCEPTIONS;
1536 return ObjectContentNone;
1539 static NSMutableArray* kit(const Vector<String>& vector)
1541 unsigned len = vector.size();
1542 NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
1543 for (unsigned x = 0; x < len; x++)
1544 [array addObject:vector[x]];
1548 static String parameterValue(const Vector<String>& paramNames, const Vector<String>& paramValues, const String& name)
1550 size_t size = paramNames.size();
1551 ASSERT(size == paramValues.size());
1552 for (size_t i = 0; i < size; ++i) {
1553 if (equalIgnoringCase(paramNames[i], name))
1554 return paramValues[i];
1559 static NSView *pluginView(WebFrame *frame, WebPluginPackage *pluginPackage,
1560 NSArray *attributeNames, NSArray *attributeValues, NSURL *baseURL,
1561 DOMElement *element, BOOL loadManually)
1563 WebHTMLView *docView = (WebHTMLView *)[[frame frameView] documentView];
1564 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1566 WebPluginController *pluginController = [docView _pluginController];
1568 // Store attributes in a dictionary so they can be passed to WebPlugins.
1569 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
1571 [pluginPackage load];
1572 Class viewFactory = [pluginPackage viewFactory];
1575 NSDictionary *arguments = nil;
1577 if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
1578 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1579 baseURL, WebPlugInBaseURLKey,
1580 attributes, WebPlugInAttributesKey,
1581 pluginController, WebPlugInContainerKey,
1582 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1583 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1584 element, WebPlugInContainingElementKey,
1586 LOG(Plugins, "arguments:\n%@", arguments);
1587 } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
1588 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
1589 baseURL, WebPluginBaseURLKey,
1590 attributes, WebPluginAttributesKey,
1591 pluginController, WebPluginContainerKey,
1592 element, WebPlugInContainingElementKey,
1594 LOG(Plugins, "arguments:\n%@", arguments);
1597 view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
1598 [attributes release];
1602 class PluginWidget : public PluginViewBase {
1604 PluginWidget(NSView *view = 0)
1605 : PluginViewBase(view)
1610 virtual void invalidateRect(const IntRect& rect)
1612 [platformWidget() setNeedsDisplayInRect:rect];
1616 #if ENABLE(NETSCAPE_PLUGIN_API)
1618 class NetscapePluginWidget : public PluginWidget {
1620 NetscapePluginWidget(WebBaseNetscapePluginView *view)
1621 : PluginWidget(view)
1625 #if USE(ACCELERATED_COMPOSITING)
1626 virtual PlatformLayer* platformLayer() const
1628 return [(WebBaseNetscapePluginView *)platformWidget() pluginLayer];
1632 virtual bool getFormValue(String& value)
1634 NSString* nsValue = 0;
1635 if ([(WebBaseNetscapePluginView *)platformWidget() getFormValue:&nsValue]) {
1638 value = String(nsValue);
1645 virtual void handleEvent(Event* event)
1647 Frame* frame = Frame::frameForWidget(this);
1651 NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
1652 if (event->type() == eventNames().mousemoveEvent)
1653 [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
1654 else if (event->type() == eventNames().mouseoverEvent)
1655 [(WebBaseNetscapePluginView *)platformWidget() handleMouseEntered:currentNSEvent];
1656 else if (event->type() == eventNames().mouseoutEvent)
1657 [(WebBaseNetscapePluginView *)platformWidget() handleMouseExited:currentNSEvent];
1661 virtual void notifyWidget(WidgetNotification notification)
1663 switch (notification) {
1664 case WillPaintFlattened: {
1665 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1666 [(WebBaseNetscapePluginView *)platformWidget() cacheSnapshot];
1667 END_BLOCK_OBJC_EXCEPTIONS;
1670 case DidPaintFlattened: {
1671 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1672 [(WebBaseNetscapePluginView *)platformWidget() clearCachedSnapshot];
1673 END_BLOCK_OBJC_EXCEPTIONS;
1680 #if USE(PLUGIN_HOST_PROCESS)
1681 #define NETSCAPE_PLUGIN_VIEW WebHostedNetscapePluginView
1683 #define NETSCAPE_PLUGIN_VIEW WebNetscapePluginView
1686 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1688 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& size, HTMLPlugInElement* element, const KURL& url,
1689 const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1691 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1693 ASSERT(paramNames.size() == paramValues.size());
1697 WebView *webView = getWebView(m_webFrame.get());
1698 SEL selector = @selector(webView:plugInViewWithArguments:);
1700 Document* document = core(m_webFrame.get())->document();
1701 NSURL *baseURL = document->baseURL();
1702 NSURL *pluginURL = url;
1704 // <rdar://problem/8366089>: AppleConnect has a bug where it does not
1705 // understand the parameter names specified in the <object> element that
1706 // embeds its plug-in. This site-specific hack works around the issue by
1707 // converting the parameter names to lowercase before passing them to the
1709 Frame* frame = core(m_webFrame.get());
1710 NSMutableArray *attributeKeys = kit(paramNames);
1711 if (frame && frame->settings()->needsSiteSpecificQuirks() && equalIgnoringCase(mimeType, "application/x-snkp")) {
1712 for (NSUInteger i = 0; i < [attributeKeys count]; ++i)
1713 [attributeKeys replaceObjectAtIndex:i withObject:[[attributeKeys objectAtIndex:i] lowercaseString]];
1716 if ([[webView UIDelegate] respondsToSelector:selector]) {
1717 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:attributeKeys];
1718 NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1719 attributes, WebPlugInAttributesKey,
1720 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
1721 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
1722 kit(element), WebPlugInContainingElementKey,
1723 // FIXME: We should be passing base URL, see <https://bugs.webkit.org/show_bug.cgi?id=35215>.
1724 pluginURL, WebPlugInBaseURLKey, // pluginURL might be nil, so add it last
1727 NSView *view = CallUIDelegate(webView, selector, arguments);
1729 [attributes release];
1730 [arguments release];
1733 return adoptRef(new PluginWidget(view));
1737 WebBasePluginPackage *pluginPackage;
1738 if (mimeType.isEmpty()) {
1740 pluginPackage = nil;
1742 MIMEType = mimeType;
1743 pluginPackage = [webView _pluginForMIMEType:mimeType];
1746 NSString *extension = [[pluginURL path] pathExtension];
1747 if (!pluginPackage && [extension length] && ![MIMEType length]) {
1748 pluginPackage = [webView _pluginForExtension:extension];
1749 if (pluginPackage) {
1750 NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
1751 if ([newMIMEType length] != 0)
1752 MIMEType = newMIMEType;
1758 if (pluginPackage) {
1759 if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1760 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, attributeKeys, kit(paramValues), baseURL, kit(element), loadManually);
1762 #if ENABLE(NETSCAPE_PLUGIN_API)
1763 else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1764 WebBaseNetscapePluginView *pluginView = [[[NETSCAPE_PLUGIN_VIEW alloc]
1765 initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1766 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1770 attributeKeys:attributeKeys
1771 attributeValues:kit(paramValues)
1772 loadManually:loadManually
1773 element:element] autorelease];
1775 return adoptRef(new NetscapePluginWidget(pluginView));
1779 errorCode = WebKitErrorCannotFindPlugIn;
1781 if (!errorCode && !view)
1782 errorCode = WebKitErrorCannotLoadPlugIn;
1784 if (errorCode && m_webFrame) {
1785 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
1786 if (implementations->plugInFailedWithErrorFunc) {
1787 KURL pluginPageURL = document->completeURL(stripLeadingAndTrailingHTMLSpaces(parameterValue(paramNames, paramValues, "pluginspage")));
1788 if (!pluginPageURL.protocolInHTTPFamily())
1789 pluginPageURL = KURL();
1790 NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1792 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1793 contentURL:pluginURL pluginPageURL:pluginPageURL pluginName:pluginName MIMEType:MIMEType];
1794 CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1795 @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1803 return adoptRef(new PluginWidget(view));
1805 END_BLOCK_OBJC_EXCEPTIONS;
1810 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1812 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1814 WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[m_webFrame.get() _dataSource] representation];
1816 NSView *pluginView = pluginWidget->platformWidget();
1818 #if ENABLE(NETSCAPE_PLUGIN_API)
1819 if ([pluginView isKindOfClass:[NETSCAPE_PLUGIN_VIEW class]])
1820 [representation _redirectDataToManualLoader:(NETSCAPE_PLUGIN_VIEW *)pluginView forPluginView:pluginView];
1825 WebHTMLView *documentView = (WebHTMLView *)[[m_webFrame.get() frameView] documentView];
1826 ASSERT([documentView isKindOfClass:[WebHTMLView class]]);
1827 [representation _redirectDataToManualLoader:[documentView _pluginController] forPluginView:pluginView];
1830 END_BLOCK_OBJC_EXCEPTIONS;
1833 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const KURL& baseURL,
1834 const Vector<String>& paramNames, const Vector<String>& paramValues)
1836 #if ENABLE(JAVA_BRIDGE)
1837 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1841 NSString *MIMEType = @"application/x-java-applet";
1843 WebView *webView = getWebView(m_webFrame.get());
1845 WebBasePluginPackage *pluginPackage = [webView _pluginForMIMEType:MIMEType];
1847 if (pluginPackage) {
1848 if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
1849 // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
1850 NSMutableArray *names = kit(paramNames);
1851 NSMutableArray *values = kit(paramValues);
1852 if (parameterValue(paramNames, paramValues, "width").isNull()) {
1853 [names addObject:@"width"];
1854 [values addObject:[NSString stringWithFormat:@"%d", size.width()]];
1856 if (parameterValue(paramNames, paramValues, "height").isNull()) {
1857 [names addObject:@"height"];
1858 [values addObject:[NSString stringWithFormat:@"%d", size.height()]];
1860 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, names, values, baseURL, kit(element), NO);
1862 return adoptRef(new PluginWidget(view));
1864 #if ENABLE(NETSCAPE_PLUGIN_API)
1865 else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1866 view = [[[NETSCAPE_PLUGIN_VIEW alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1867 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
1871 attributeKeys:kit(paramNames)
1872 attributeValues:kit(paramValues)
1874 element:element] autorelease];
1876 return adoptRef(new NetscapePluginWidget(static_cast<WebBaseNetscapePluginView *>(view)));
1878 ASSERT_NOT_REACHED();
1884 WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(getWebView(m_webFrame.get()));
1885 if (implementations->plugInFailedWithErrorFunc) {
1886 NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
1887 NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable contentURL:nil pluginPageURL:nil pluginName:pluginName MIMEType:MIMEType];
1888 CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
1889 @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
1894 END_BLOCK_OBJC_EXCEPTIONS;
1895 #endif // ENABLE(JAVA_BRIDGE)
1899 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1900 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize& size, HTMLMediaElement* element, const KURL& url,
1901 const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType)
1903 BEGIN_BLOCK_OBJC_EXCEPTIONS;
1905 ASSERT(paramNames.size() == paramValues.size());
1909 WebView *webView = getWebView(m_webFrame.get());
1912 SEL selector = @selector(webView:plugInViewWithArguments:);
1914 if ([[webView UIDelegate] respondsToSelector:selector]) {
1915 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:kit(paramNames)];
1916 NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
1917 attributes, WebPlugInAttributesKey,
1918 [NSNumber numberWithInt:WebPlugInModeEmbed], WebPlugInModeKey,
1919 [NSNumber numberWithBool:YES], WebPlugInShouldLoadMainResourceKey,
1920 kit(element), WebPlugInContainingElementKey,
1921 URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
1924 NSView *view = CallUIDelegate(webView, selector, arguments);
1926 [attributes release];
1927 [arguments release];
1930 return adoptRef(new PluginWidget(view));
1933 WebBasePluginPackage *pluginPackage = [webView _videoProxyPluginForMIMEType:mimeType];
1934 Document* document = core(m_webFrame.get())->document();
1935 NSURL *baseURL = document->baseURL();
1938 if (pluginPackage) {
1939 if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
1940 view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, kit(paramNames), kit(paramValues), baseURL, kit(element), false);
1942 errorCode = WebKitErrorCannotFindPlugIn;
1944 if (!errorCode && !view)
1945 errorCode = WebKitErrorCannotLoadPlugIn;
1948 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1949 contentURL:URL pluginPageURL:nil pluginName:[pluginPackage pluginInfo].name MIMEType:mimeType];
1950 WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
1951 error:error DOMElement:kit(element)] autorelease];
1957 return adoptRef(new PluginWidget(view));
1959 END_BLOCK_OBJC_EXCEPTIONS;
1964 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget)
1966 [WebPluginController pluginViewHidden:widget->platformWidget()];
1969 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget)
1971 [WebPluginController addPlugInView:widget->platformWidget()];
1974 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1976 String WebFrameLoaderClient::overrideMediaType() const
1978 NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle];
1980 return overrideType;
1984 void WebFrameLoaderClient::documentElementAvailable() {
1987 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1989 WebView *webView = getWebView(m_webFrame.get());
1990 WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
1992 if (implementations->didClearWindowObjectForFrameInScriptWorldFunc) {
1993 CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameInScriptWorldFunc,
1994 webView, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:), m_webFrame.get(), [WebScriptWorld findOrCreateWorld:world]);
1998 if (world != mainThreadNormalWorld())
2001 Frame *frame = core(m_webFrame.get());
2002 ScriptController *script = frame->script();
2004 if (implementations->didClearWindowObjectForFrameFunc) {
2005 CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:),
2006 script->windowScriptObject(), m_webFrame.get());
2007 } else if (implementations->windowScriptObjectAvailableFunc) {
2008 CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:),
2009 script->windowScriptObject());
2012 if ([webView scriptDebugDelegate]) {
2013 [m_webFrame.get() _detachScriptDebugger];
2014 [m_webFrame.get() _attachScriptDebugger];
2018 void WebFrameLoaderClient::registerForIconNotification(bool listen)
2020 #if ENABLE(ICONDATABASE)
2021 [[m_webFrame.get() webView] _registerForIconNotification:listen];
2025 void WebFrameLoaderClient::didPerformFirstNavigation() const
2027 WebPreferences *preferences = [[m_webFrame.get() webView] preferences];
2028 if ([preferences automaticallyDetectsCacheModel] && [preferences cacheModel] < WebCacheModelDocumentBrowser)
2029 [preferences setCacheModel:WebCacheModelDocumentBrowser];
2032 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
2034 return WebFrameNetworkingContext::create(core(m_webFrame.get()));
2037 #if ENABLE(JAVA_BRIDGE)
2038 jobject WebFrameLoaderClient::javaApplet(NSView* view)
2040 if ([view respondsToSelector:@selector(webPlugInGetApplet)])
2041 return [view webPlugInGetApplet];
2043 // Compatibility with older versions of Java.
2044 // FIXME: Do we still need this?
2045 if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
2046 return [view pollForAppletInWindow:[[m_webFrame.get() frameView] window]];
2052 @implementation WebFramePolicyListener
2055 JSC::initializeThreading();
2056 WTF::initializeMainThreadToProcessMainThread();
2057 WebCoreObjCFinalizeOnMainThread(self);
2060 - (id)initWithWebCoreFrame:(Frame*)frame
2080 if (WebCoreObjCScheduleDeallocateOnMainThread([WebFramePolicyListener class], self))
2090 ASSERT_MAIN_THREAD();
2096 - (void)receivedPolicyDecision:(PolicyAction)action
2098 RefPtr<Frame> frame = adoptRef(m_frame);
2101 static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
2106 [self receivedPolicyDecision:PolicyIgnore];
2111 [self receivedPolicyDecision:PolicyDownload];
2116 [self receivedPolicyDecision:PolicyUse];
2121 [self receivedPolicyDecision:PolicyUse];