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