WebFrameLoaderClient.mm revision 2daae5fd11344eaa88a0d92b0f6d65f8d2255c00
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 138using namespace WebCore; 139using namespace HTMLNames; 140using 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. 153NSString *WebPluginBaseURLKey = @"WebPluginBaseURL"; 154NSString *WebPluginAttributesKey = @"WebPluginAttributes"; 155NSString *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 164static 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 177static 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 202static 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 211WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame) 212 : m_webFrame(webFrame) 213 , m_policyFunction(0) 214{ 215} 216 217void WebFrameLoaderClient::frameLoaderDestroyed() 218{ 219 [m_webFrame.get() _clearCoreFrame]; 220 delete this; 221} 222 223bool WebFrameLoaderClient::hasWebView() const 224{ 225 return [m_webFrame.get() webView] != nil; 226} 227 228void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader) 229{ 230 [dataSource(loader) _makeRepresentation]; 231} 232 233bool 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 244void WebFrameLoaderClient::forceLayout() 245{ 246 NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView]; 247 [view setNeedsLayout:YES]; 248 [view layout]; 249} 250 251void 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 268void WebFrameLoaderClient::setCopiesOnScroll() 269{ 270 [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES]; 271} 272 273void 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 281void WebFrameLoaderClient::detachedFromParent3() 282{ 283 [m_webFrame->_private->webFrameView release]; 284 m_webFrame->_private->webFrameView = nil; 285} 286 287void 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 302void 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 344bool 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 357void 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 377void 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 391bool 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 404void 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) 423bool 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 443bool 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 455void 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 471void 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 481NSCachedURLResponse* 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 494void 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 504void 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 519void 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 534void 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 542void 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 550void 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 558void 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 568void 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 576void 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 584void 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 592void 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 600void 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 608void 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 617void 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 627void 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 636void WebFrameLoaderClient::dispatchDidChangeIcons() 637{ 638 // FIXME: Implement this to allow container to update favicon. 639} 640 641void 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 654void 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 666void 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 678void 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 686void 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 698void 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 715void 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 723Frame* 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 740void WebFrameLoaderClient::dispatchShow() 741{ 742 WebView *webView = getWebView(m_webFrame.get()); 743 [[webView _UIDelegateForwarder] webViewShow:webView]; 744} 745 746void 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 758void 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 769void 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 780void WebFrameLoaderClient::cancelPolicyCheck() 781{ 782 [m_policyListener.get() invalidate]; 783 m_policyListener = nil; 784 m_policyFunction = 0; 785} 786 787void 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 793void 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 812void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader) 813{ 814} 815 816void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader) 817{ 818 [dataSource(loader) _revertToProvisionalState]; 819} 820 821void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error) 822{ 823 [dataSource(loader) _setMainDocumentError:error]; 824} 825 826void WebFrameLoaderClient::willChangeEstimatedProgress() 827{ 828 [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey]; 829} 830 831void WebFrameLoaderClient::didChangeEstimatedProgress() 832{ 833 [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey]; 834} 835 836void WebFrameLoaderClient::postProgressStartedNotification() 837{ 838 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())]; 839} 840 841void WebFrameLoaderClient::postProgressEstimateChangedNotification() 842{ 843 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())]; 844} 845 846void WebFrameLoaderClient::postProgressFinishedNotification() 847{ 848 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())]; 849} 850 851void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready) 852{ 853 [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready]; 854} 855 856void 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 864void 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 870void 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 876void 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 883void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) 884{ 885 [dataSource(loader) _finishedLoading]; 886} 887 888void 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 917void 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 946bool 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 954bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const 955{ 956 return true; 957} 958 959void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const 960{ 961} 962 963void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const 964{ 965} 966 967void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const 968{ 969} 970 971void 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 984void 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 992void 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 1002ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request) 1003{ 1004 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()]; 1005} 1006 1007ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request) 1008{ 1009 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()]; 1010} 1011 1012ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request) 1013{ 1014 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()]; 1015} 1016 1017ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request) 1018{ 1019 return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()]; 1020} 1021 1022ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response) 1023{ 1024 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()]; 1025} 1026 1027ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response) 1028{ 1029 return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()]; 1030} 1031 1032ResourceError 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 1042bool 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 1050bool 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 1058bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const 1059{ 1060 return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType]; 1061} 1062 1063bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const 1064{ 1065 return [WebView canShowMIMETypeAsHTML:MIMEType]; 1066} 1067 1068bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const 1069{ 1070 return [WebView _representationExistsForURLScheme:URLScheme]; 1071} 1072 1073String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const 1074{ 1075 return [WebView _generatedMIMETypeForURLScheme:URLScheme]; 1076} 1077 1078void 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 1087void 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 1100void 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 1122void 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 1141void WebFrameLoaderClient::didFinishLoad() 1142{ 1143 [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil]; 1144} 1145 1146void 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 1172PassRefPtr<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 1183void 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 1206void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame) 1207{ 1208 WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]); 1209 cachedFrame->setCachedFramePlatformData(webPlatformData); 1210} 1211 1212void 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 1227void 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 1303void WebFrameLoaderClient::didSaveToPageCache() 1304{ 1305} 1306 1307void WebFrameLoaderClient::didRestoreFromPageCache() 1308{ 1309} 1310 1311void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool) 1312{ 1313} 1314 1315RetainPtr<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 1329void 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 1342String 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 1357static 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 1365NSDictionary *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 1405bool 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 1411PassRefPtr<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 1445void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page* oldPage) 1446{ 1447} 1448 1449void 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 1459ObjectContentType 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 1526static 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 1535static 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 1546static 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 1589class PluginWidget : public PluginViewBase { 1590public: 1591 PluginWidget(NSView *view = 0) 1592 : PluginViewBase(view) 1593 { 1594 } 1595 1596private: 1597 virtual void invalidateRect(const IntRect& rect) 1598 { 1599 [platformWidget() setNeedsDisplayInRect:rect]; 1600 } 1601}; 1602 1603#if ENABLE(NETSCAPE_PLUGIN_API) 1604 1605class NetscapePluginWidget : public PluginWidget { 1606public: 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 1634private: 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 1662PassRefPtr<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 1784void 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 1807PassRefPtr<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) 1874PassRefPtr<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 1938void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget) 1939{ 1940 [WebPluginController pluginViewHidden:widget->platformWidget()]; 1941} 1942 1943void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget) 1944{ 1945 [WebPluginController addPlugInView:widget->platformWidget()]; 1946} 1947 1948#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1949 1950String WebFrameLoaderClient::overrideMediaType() const 1951{ 1952 NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle]; 1953 if (overrideType) 1954 return overrideType; 1955 return String(); 1956} 1957 1958void WebFrameLoaderClient::documentElementAvailable() { 1959} 1960 1961void 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 1992void WebFrameLoaderClient::registerForIconNotification(bool listen) 1993{ 1994#if ENABLE(ICONDATABASE) 1995 [[m_webFrame.get() webView] _registerForIconNotification:listen]; 1996#endif 1997} 1998 1999void 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 2006PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext() 2007{ 2008 return WebFrameNetworkingContext::create(core(m_webFrame.get())); 2009} 2010 2011#if ENABLE(JAVA_BRIDGE) 2012jobject 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