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