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