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