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